我想用Python编写一个函数,根据输入索引的值返回不同的固定值。

在其他语言中,我会使用switch或case语句,但Python似乎没有switch语句。在此场景中,推荐的Python解决方案是什么?


当前回答

我做了一个switch-case实现,它在外部不太使用if(它仍然在类中使用if)。

class SwitchCase(object):
    def __init__(self):
        self._cases = dict()

    def add_case(self,value, fn):
        self._cases[value] = fn

    def add_default_case(self,fn):
        self._cases['default']  = fn

    def switch_case(self,value):
        if value in self._cases.keys():
            return self._cases[value](value)
        else:
            return self._cases['default'](0)

这样使用:

from switch_case import SwitchCase
switcher = SwitchCase()
switcher.add_case(1, lambda x:x+1)
switcher.add_case(2, lambda x:x+3)
switcher.add_default_case(lambda _:[1,2,3,4,5])

print switcher.switch_case(1) #2
print switcher.switch_case(2) #5
print switcher.switch_case(123) #[1, 2, 3, 4, 5]

其他回答

除了字典方法(我很喜欢,BTW),您还可以使用if elif else来获得switch/case/default功能:

if x == 'a':
    # Do the thing
elif x == 'b':
    # Do the other thing
if x in 'bc':
    # Fall-through by not using elif, but now the default case includes case 'a'!
elif x in 'xyz':
    # Do yet another thing
else:
    # Do the default

当然,这与switch/case不同——你不可能像放弃break语句那样轻易地通过,但你可以进行更复杂的测试。它的格式比一系列嵌套的if更好,尽管在功能上更接近。

如果您想要默认值,可以使用dictionary get(key[,default])函数:

def f(x):
    return {
        'a': 1,
        'b': 2
    }.get(x, 9)    # 9 will be returned default if x is not found

运行函数的解决方案:

result = {
    'case1':     foo1, 
    'case2':     foo2,
    'case3':     foo3,
}.get(option)(parameters_optional)

其中foo1()、foo2()和foo3()是函数

示例1(带参数):

option = number['type']
result = {
    'number':     value_of_int,  # result = value_of_int(number['value'])
    'text':       value_of_text, # result = value_of_text(number['value'])
    'binary':     value_of_bin,  # result = value_of_bin(number['value'])
}.get(option)(value['value'])

示例2(无参数):

option = number['type']
result = {
    'number':     func_for_number, # result = func_for_number()
    'text':       func_for_text,   # result = func_for_text()
    'binary':     func_for_bin,    # result = func_for_bin()
}.get(option)()

示例4(仅限值):

option = number['type']
result = {
    'number':    lambda: 10,       # result = 10
    'text':      lambda: 'ten',    # result = 'ten'
    'binary':    lambda: 0b101111, # result = 47
}.get(option)()

当我需要一个简单的switchcase来调用一堆方法而不仅仅是打印一些文本时,下面的方法适用于我的情况。在玩了lambda和globals之后,我觉得这是迄今为止最简单的选择。也许它也会帮助某人:

def start():
    print("Start")

def stop():
    print("Stop")

def print_help():
    print("Help")

def choose_action(arg):
    return {
        "start": start,
        "stop": stop,
        "help": print_help,
    }.get(arg, print_help)

argument = sys.argv[1].strip()
choose_action(argument)()  # calling a method from the given string

我要把我的两分钱放在这里。Python中没有case/switch语句的原因是因为Python遵循“只有一种正确的方法”的原则。很明显,您可以想出各种方法来重新创建switch/case功能,但实现这一点的Python方法是if/elf构造。即。,

if something:
    return "first thing"
elif somethingelse:
    return "second thing"
elif yetanotherthing:
    return "third thing"
else:
    return "default thing"

我只是觉得PEP 8应该在这里获得认可。Python的一个优点是它的简单和优雅。这在很大程度上源于PEP8中提出的原则,包括“只有一种正确的方法可以做某事。”