我想在Python中编写一个函数,根据输入索引的值返回不同的固定值。
在其他语言中,我会使用switch
或case
语句,但Python似乎没有switch
语句。在这种情况下,有哪些推荐的Python解决方案?
我想在Python中编写一个函数,根据输入索引的值返回不同的固定值。
在其他语言中,我会使用switch
或case
语句,但Python似乎没有switch
语句。在这种情况下,有哪些推荐的Python解决方案?
我只是想在这里提出一些建议。Python没有case/switch语句的原因是Python遵循“有且仅有一种正确的做法”的原则。显然,你可以想出各种重新创建switch/case功能的方式,但完成这个任务的Pythonic方式是使用if/elif结构,例如:
if something:
return "first thing"
elif somethingelse:
return "second thing"
elif yetanotherthing:
return "third thing"
else:
return "default thing"
我认为 PEP 8 在这里值得一提。 Python 最美妙的地方之一就是它的简洁与优雅,这很大程度上源自 PEP 8 中规定的原则,包括“只有一种正确的做法”。
假设你不仅想返回一个值,而是想使用能够改变对象的方法。按照这里提出的方法:
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' 然后评估返回的函数调用。
如果你有一个复杂的case块,可以考虑使用函数字典查找表...
如果你以前没有这样做过,最好进入调试器并查看字典如何查找每个函数。
注意: 不要在case /字典查找中使用“()”,否则它会在创建字典/ case块时调用您的每个函数。记住这一点,因为您只想使用哈希样式查找一次调用每个函数。
def first_case():
print "first"
def second_case():
print "second"
def third_case():
print "third"
mycase = {
'first': first_case, #do not use ()
'second': second_case, #do not use ()
'third': third_case #do not use ()
}
myfunc = mycase['first']
myfunc()
macro switch(arg1):
while True:
cont=False
val=%arg1%
socket case(arg2):
if val==%arg2% or cont:
cont=True
socket
socket else:
socket
break
这可以像这样使用:
a=3
switch(a):
case(0):
print("Zero")
case(1):
print("Smaller than 2"):
break
else:
print ("greater than 1")
因此,将其在Python中翻译为:
a=3
while True:
cont=False
if a==0 or cont:
cont=True
print ("Zero")
if a==1 or cont:
cont=True
print ("Smaller than 2")
break
print ("greater than 1")
break
while True:
有什么意义呢?它最终会到达生成的Python代码底部的break
,因此我认为while True:
和break
都可以被删除。此外,如果用户在自己的代码中使用相同的名称,ESPY是否足够聪明以更改cont
的名称?无论如何,我想使用原始的Python,所以我不会使用这个,但它仍然很酷。对于纯粹的酷度,加1。 - ArtOfWarfarewhile True:
和 break
的原因是允许但不要求穿透。 - Solomon Uckoelif
链,在更大或更复杂的情况下使用dict
。它还针对某些情况建议使用一组visit_
方法(许多服务器框架使用的样式)。def dispatch(self, value):
method_name = 'visit_' + str(value)
method = getattr(self, method_name)
method()
常见问题解答中也提到了PEP 275,它是为了让官方做出一次性决定,是否添加类似C语言的switch语句。但该PEP实际上被推迟至Python 3,并且只有在作为单独提案的PEP 3103中被正式拒绝。答案当然是否定的,但这两个PEP都链接到其他信息,如果您对原因或历史感兴趣。
有一件事情被多次提及(可以在PEP 275中看到,尽管它被削减为实际建议),那就是如果你真的很烦恼于处理4种情况需要8行代码,而在C或Bash中只需要6行,你总是可以写成这样:
if x == 1: print('first')
elif x == 2: print('second')
elif x == 3: print('third')
else: print('did not place')
这并不完全符合PEP 8的规范,但易读性较好且不太不符惯用语。
dataclass
和一些零散的提议来处理总和类型的更强大的enum
,或者各种不同类型的语句局部绑定的提议(如PEP 3150,或者目前正在-ideas上讨论的一组提议)而改变。但到目前为止,还没有。也有偶尔提出Perl 6风格的匹配提议,这基本上是从elif
到正则表达式到单分派类型切换的混杂。我发现一种常见的开关结构:
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版本不是语句,而是表达式,其会被计算为一个值。
parameter
和p1==parameter
。 - Bob Steinf = lambda x: 'a' if x==0 else 'b' if x==1 else 'c'
。当我稍后调用f(2)
时,我得到了'c'
;f(1)
,'b'
;以及f(0)
,'a'
。至于p1(x),它表示一个谓词;只要它返回True
或False
,无论是函数调用还是表达式,都可以。 - leo扩展“字典作为开关”思想。 如果您想为开关使用默认值:
def f(x):
try:
return {
'a': 1,
'b': 2,
}[x]
except KeyError:
return 'default'
get
可能会让代码更简洁。 - Mike Grahamresult = {
'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)
在字典中查找"lambda x: x - 2"
,并将其用于x=23
。
.get('xxx', lambda x: x - 22)(44)
在字典中找不到它并使用默认值"lambda x: x - 22"
,其中x=44
。
你可以使用一个派发的字典:
#!/usr/bin/env python
def case1():
print("This is case 1")
def case2():
print("This is case 2")
def case3():
print("This is case 3")
token_dict = {
"case1" : case1,
"case2" : case2,
"case3" : case3,
}
def main():
cases = ("case1", "case3", "case2", "case1")
for case in cases:
token_dict[case]()
if __name__ == '__main__':
main()
输出:
This is case 1
This is case 3
This is case 2
This is case 1
读完被接受的答案后,我感到相当困惑,但这篇文章把所有问题都解决了:
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";
}
}
查看源代码以了解有关将字典映射到函数的更多信息。