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

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


当前回答

定义:

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()在查找值之前合并字典。它仍然比我想象的更丑,但它的基本效率是对表达式使用散列查找,而不是循环所有键。

其他回答

我喜欢Mark Bies的回答

由于x变量必须使用两次,我将lambda函数修改为无参数。

我必须运行结果[value](value)

In [2]: result = {
    ...:   'a': lambda x: 'A',
    ...:   'b': lambda x: 'B',
    ...:   'c': lambda x: 'C'
    ...: }
    ...: result['a']('a')
    ...: 
Out[2]: 'A'

In [3]: result = {
    ...:   'a': lambda : 'A',
    ...:   'b': lambda : 'B',
    ...:   'c': lambda : 'C',
    ...:   None: lambda : 'Nothing else matters'

    ...: }
    ...: result['a']()
    ...: 
Out[3]: 'A'

编辑:我注意到我可以在字典中使用None类型。因此,这将模拟交换机;其他情况

我使用的解决方案:

这里发布的两个解决方案的组合,相对容易阅读,并支持默认值。

result = {
  'a': lambda x: x * 5,
  'b': lambda x: x + 7,
  'c': lambda x: x - 2
}.get(whatToUse, lambda x: x - 22)(value)

哪里

.get('c', lambda x: x - 22)(23)

在dict中查找“lambda x:x-2”,并在x=23时使用它

.get('xxx', lambda x: x - 22)(44)

在dict中找不到它,使用默认的“lambda x:x-22”,x=44。

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

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”然后计算返回的函数调用。

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

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

易于记忆:

while True:
    try:
        x = int(input("Enter a numerical input: "))
    except:
        print("Invalid input - please enter a Integer!");
    if x==1:
        print("good");
    elif x==2:
        print("bad");
    elif x==3:
        break
    else:
        print ("terrible");