我想用Python编写一个函数,根据输入索引的值返回不同的固定值。
在其他语言中,我会使用switch或case语句,但Python似乎没有switch语句。在此场景中,推荐的Python解决方案是什么?
我想用Python编写一个函数,根据输入索引的值返回不同的固定值。
在其他语言中,我会使用switch或case语句,但Python似乎没有switch语句。在此场景中,推荐的Python解决方案是什么?
当前回答
我一直喜欢这样做
result = {
'a': lambda x: x * 5,
'b': lambda x: x + 7,
'c': lambda x: x - 2
}[value](x)
从这里开始
其他回答
我要把我的两分钱放在这里。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中提出的原则,包括“只有一种正确的方法可以做某事。”
Python 3.10(2021)引入了match-case语句,该语句提供了Pythons“switch”的一流实现。例如:
def f(x):
match x:
case 'a':
return 1
case 'b':
return 2
case _:
return 0 # 0 is the default case if x is not found
match-case语句比这个简单的示例强大得多。
以下原始答案写于2008年,当时还未提供匹配案例:
你可以用字典:
def f(x):
return {
'a': 1,
'b': 2,
}[x]
扩展Greg Hewgill的答案-我们可以使用装饰器封装字典解决方案:
def case(callable):
"""switch-case decorator"""
class case_class(object):
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
def do_call(self):
return callable(*self.args, **self.kwargs)
return case_class
def switch(key, cases, default=None):
"""switch-statement"""
ret = None
try:
ret = case[key].do_call()
except KeyError:
if default:
ret = default.do_call()
finally:
return ret
然后可以将其与@case decorator一起使用
@case
def case_1(arg1):
print 'case_1: ', arg1
@case
def case_2(arg1, arg2):
print 'case_2'
return arg1, arg2
@case
def default_case(arg1, arg2, arg3):
print 'default_case: ', arg1, arg2, arg3
ret = switch(somearg, {
1: case_1('somestring'),
2: case_2(13, 42)
}, default_case(123, 'astring', 3.14))
print ret
好消息是,这已经在NeoPySwitch模块中完成。只需使用pip进行安装:
pip install NeoPySwitch
当我需要一个简单的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
switch语句只是if/elif/else的语法糖。任何控制语句所做的都是基于某个条件(即决策路径)来授权作业。为了将其包装到模块中并能够基于其唯一id调用作业,可以使用继承和Python中的任何方法都是虚拟的这一事实来提供派生类特定的作业实现,作为特定的“case”处理程序:
#!/usr/bin/python
import sys
class Case(object):
"""
Base class which specifies the interface for the "case" handler.
The all required arbitrary arguments inside "execute" method will be
provided through the derived class
specific constructor
@note in Python, all class methods are virtual
"""
def __init__(self, id):
self.id = id
def pair(self):
"""
Pairs the given id of the "case" with
the instance on which "execute" will be called
"""
return (self.id, self)
def execute(self): # Base class virtual method that needs to be overridden
pass
class Case1(Case):
def __init__(self, id, msg):
self.id = id
self.msg = msg
def execute(self): # Override the base class method
print("<Case1> id={}, message: \"{}\"".format(str(self.id), self.msg))
class Case2(Case):
def __init__(self, id, n):
self.id = id
self.n = n
def execute(self): # Override the base class method
print("<Case2> id={}, n={}.".format(str(self.id), str(self.n)))
print("\n".join(map(str, range(self.n))))
class Switch(object):
"""
The class which delegates the jobs
based on the given job id
"""
def __init__(self, cases):
self.cases = cases # dictionary: time complexity for the access operation is 1
def resolve(self, id):
try:
cases[id].execute()
except KeyError as e:
print("Given id: {} is wrong!".format(str(id)))
if __name__ == '__main__':
# Cases
cases=dict([Case1(0, "switch").pair(), Case2(1, 5).pair()])
switch = Switch(cases)
# id will be dynamically specified
switch.resolve(0)
switch.resolve(1)
switch.resolve(2)