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

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


当前回答

我倾向于使用字典的解决方案是:

def decision_time( key, *args, **kwargs):
    def action1()
        """This function is a closure - and has access to all the arguments"""
        pass
    def action2()
        """This function is a closure - and has access to all the arguments"""
        pass
    def action3()
        """This function is a closure - and has access to all the arguments"""
        pass

   return {1:action1, 2:action2, 3:action3}.get(key,default)()

这样做的优点是它不需要每次都对函数求值,您只需确保外部函数获得内部函数所需的所有信息。

其他回答

还可以使用列表存储案例,并通过select调用相应的函数-

cases = ['zero()', 'one()', 'two()', 'three()']

def zero():
  print "method for 0 called..."
def one():
  print "method for 1 called..."
def two():
  print "method for 2 called..."
def three():
  print "method for 3 called..."

i = int(raw_input("Enter choice between 0-3 "))

if(i<=len(cases)):
  exec(cases[i])
else:
  print "wrong choice"

也在螺丝台上进行了解释。

class switch(object):
    value = None
    def __new__(class_, value):
        class_.value = value
        return True

def case(*args):
    return any((arg == switch.value for arg in args))

用法:

while switch(n):
    if case(0):
        print "You typed zero."
        break
    if case(1, 4, 9):
        print "n is a perfect square."
        break
    if case(2):
        print "n is an even number."
    if case(2, 3, 5, 7):
        print "n is a prime number."
        break
    if case(6, 8):
        print "n is an even number."
        break
    print "Only single-digit numbers are allowed."
    break

测验:

n = 2
#Result:
#n is an even number.
#n is a prime number.
n = 11
#Result:
#Only single-digit numbers are allowed.

简单,未经测试;每个条件都是独立计算的:没有贯穿,但所有情况都会计算(尽管要打开的表达式只计算一次),除非有break语句。例如

for case in [expression]:
    if case == 1:
        print(end='Was 1. ')

    if case == 2:
        print(end='Was 2. ')
        break

    if case in (1, 2):
        print(end='Was 1 or 2. ')

    print(end='Was something. ')

指纹是1。是1或2。是什么。(该死!为什么在内联代码块中不能有尾随空格?)若表达式的计算结果为1,则为2。如果表达式的计算结果为2或Was某物。if表达式的计算结果为其他值。

def f(x):
    dictionary = {'a':1, 'b':2, 'c':3}
    return dictionary.get(x,'Not Found') 
##Returns the value for the letter x;returns 'Not Found' if x isn't a key in the dictionary

作为Mark Biek答案的一个小变化,对于像这样的不常见情况,用户有一堆函数调用要延迟,而参数要打包(而且不值得构建一堆不符合逻辑的函数),而不是这样:

d = {
    "a1": lambda: a(1),
    "a2": lambda: a(2),
    "b": lambda: b("foo"),
    "c": lambda: c(),
    "z": lambda: z("bar", 25),
    }
return d[string]()

…您可以这样做:

d = {
    "a1": (a, 1),
    "a2": (a, 2),
    "b": (b, "foo"),
    "c": (c,)
    "z": (z, "bar", 25),
    }
func, *args = d[string]
return func(*args)

这当然更短,但它是否更可读是一个悬而未决的问题…


我认为从lambda转换为partial可能更容易理解(虽然不是更简单):

d = {
    "a1": partial(a, 1),
    "a2": partial(a, 2),
    "b": partial(b, "foo"),
    "c": c,
    "z": partial(z, "bar", 25),
    }
return d[string]()

…它的优点是可以很好地处理关键字参数:

d = {
    "a1": partial(a, 1),
    "a2": partial(a, 2),
    "b": partial(b, "foo"),
    "c": c,
    "k": partial(k, key=int),
    "z": partial(z, "bar", 25),
    }
return d[string]()