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

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


当前回答

假设您不希望只返回一个值,而是希望使用更改对象上某些内容的方法。使用此处所述的方法将是:

result = {
  'a': obj.increment(x),
  'b': obj.decrement(x)
}.get(value, obj.default(x))

这里Python计算字典中的所有方法。

因此,即使您的值为“a”,对象也会递增和递减x。

解决方案:

func, args = {
  'a' : (obj.increment, (x,)),
  'b' : (obj.decrement, (x,)),
}.get(value, (obj.default, (x,)))

result = func(*args)

因此,您将得到一个包含函数及其参数的列表。这样,只返回函数指针和参数列表,而不计算result”然后计算返回的函数调用。

其他回答

我发现一种常见的交换机结构:

switch ...parameter...
case p1: v1; break;
case p2: v2; break;
default: v3;

可以用Python表示如下:

(lambda x: v1 if p1(x) else v2 if p2(x) else v3)

或以更清晰的方式格式化:

(lambda x:
     v1 if p1(x) else
     v2 if p2(x) else
     v3)

Python版本不是一个语句,而是一个表达式,其计算结果为一个值。

如果您想要默认值,可以使用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

定义:

def switch1(value, options):
  if value in options:
    options[value]()

允许您使用相当简单的语法,并将案例绑定到映射中:

def sample1(x):
  local = 'betty'
  switch1(x, {
    'a': lambda: print("hello"),
    'b': lambda: (
      print("goodbye," + local),
      print("!")),
    })

我一直试图用一种能让我摆脱“lambda:”的方式重新定义开关,但我放弃了。调整定义:

def switch(value, *maps):
  options = {}
  for m in maps:
    options.update(m)
  if value in options:
    options[value]()
  elif None in options:
    options[None]()

允许我将多个案例映射到同一代码,并提供默认选项:

def sample(x):
  switch(x, {
    _: lambda: print("other") 
    for _ in 'cdef'
    }, {
    'a': lambda: print("hello"),
    'b': lambda: (
      print("goodbye,"),
      print("!")),
    None: lambda: print("I dunno")
    })

每个复制的案例都必须在自己的字典中;switch()在查找值之前合并字典。它仍然比我想象的更丑,但它的基本效率是对表达式使用散列查找,而不是循环所有键。

扩展“dict as switch”思想。如果要为交换机使用默认值:

def f(x):
    try:
        return {
            'a': 1,
            'b': 2,
        }[x]
    except KeyError:
        return 'default'

在阅读了公认的答案后,我感到非常困惑,但这一切都清楚了:

def numbers_to_strings(argument):
    switcher = {
        0: "zero",
        1: "one",
        2: "two",
    }
    return switcher.get(argument, "nothing")

该代码类似于:

function(argument){
    switch(argument) {
        case 0:
            return "zero";
        case 1:
            return "one";
        case 2:
            return "two";
        default:
            return "nothing";
    }
}

有关字典映射到函数的详细信息,请查看源代码。