我想用Python编写一个函数,根据输入索引的值返回不同的固定值。
在其他语言中,我会使用switch或case语句,但Python似乎没有switch语句。在此场景中,推荐的Python解决方案是什么?
我想用Python编写一个函数,根据输入索引的值返回不同的固定值。
在其他语言中,我会使用switch或case语句,但Python似乎没有switch语句。在此场景中,推荐的Python解决方案是什么?
当前回答
还可以使用列表存储案例,并通过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"
也在螺丝台上进行了解释。
其他回答
我做了一个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]
仅仅将一些键映射到一些代码并不是一个真正的问题,正如大多数人在使用字典时所展示的那样。真正的诀窍是尝试模仿整个直通和中断过程。我认为我从来没有写过一个案例陈述,其中我使用了“功能”。这里有一个直通车。
def case(list): reduce(lambda b, f: (b | f[0], {False:(lambda:None),True:f[1]}[b | f[0]]())[0], list, False)
case([
(False, lambda:print(5)),
(True, lambda:print(4))
])
我真的把它想象成一个单独的陈述。我希望你能原谅这种愚蠢的格式。
reduce(
initializer=False,
function=(lambda b, f:
( b | f[0]
, { False: (lambda:None)
, True : f[1]
}[b | f[0]]()
)[0]
),
iterable=[
(False, lambda:print(5)),
(True, lambda:print(4))
]
)
我希望这是有效的Python代码。它应该能让你通过。当然,布尔检查可以是表达式,如果您希望它们被延迟求值,那么可以将它们全部封装在lambda中。在执行了列表中的一些项目之后,也不难让它被接受。只需创建元组(bool,bool,function),其中第二个bool指示是否突破或放弃。
简单,未经测试;每个条件都是独立计算的:没有贯穿,但所有情况都会计算(尽管要打开的表达式只计算一次),除非有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表达式的计算结果为其他值。
我从Twisted Python代码中学到了一种模式。
class SMTP:
def lookupMethod(self, command):
return getattr(self, 'do_' + command.upper(), None)
def do_HELO(self, rest):
return 'Howdy ' + rest
def do_QUIT(self, rest):
return 'Bye'
SMTP().lookupMethod('HELO')('foo.bar.com') # => 'Howdy foo.bar.com'
SMTP().lookupMethod('QUIT')('') # => 'Bye'
您可以在需要调度令牌和执行扩展代码段的任何时候使用它。在状态机中,您将有state_方法,并在self.state上分派。通过从基类继承并定义自己的do_方法,可以清晰地扩展此开关。通常,基类中甚至没有do_方法。
编辑:具体是如何使用的
如果是SMTP,您将收到来自网络的HELO。相关代码(来自twisted/mail/smtp.py,根据我们的情况进行了修改)如下
class SMTP:
# ...
def do_UNKNOWN(self, rest):
raise NotImplementedError, 'received unknown command'
def state_COMMAND(self, line):
line = line.strip()
parts = line.split(None, 1)
if parts:
method = self.lookupMethod(parts[0]) or self.do_UNKNOWN
if len(parts) == 2:
return method(parts[1])
else:
return method('')
else:
raise SyntaxError, 'bad syntax'
SMTP().state_COMMAND(' HELO foo.bar.com ') # => Howdy foo.bar.com
您将收到“HELO foo.bar.com”(或者您可能会收到“QUIT”或“RCPT TO:foo”)。这被标记为['HELO','foo.bar.com']。实际的方法查找名称取自部件[0]。
(原始方法也称为state_COMMAND,因为它使用相同的模式来实现状态机,即getattr(self,'state_'+self.mode))
def f(x):
return 1 if x == 'a' else\
2 if x in 'bcd' else\
0 #default
简短易读,具有默认值,支持条件和返回值中的表达式。
然而,它的效率不如字典解决方案。例如,Python必须在返回默认值之前扫描所有条件。