如果我有一个带有多个条件语句的函数,其中每个分支都执行从函数返回。我应该使用多个if语句,还是使用/ elif / else?例如,假设我有一个功能:
def example(x):
if x > 0:
return 'positive'
if x < 0:
return 'negative'
return 'zero'
写作是否更好:
def example(x):
if x > 0:
return 'positive'
elif x < 0:
return 'negative'
else:
return 'zero'
两者都有相同的结果,但是效率更高或被认为比另一种更惯用?
修改
有几个人说在第一个例子中,if语句总是被评估,但对我来说似乎并非如此
例如,如果我运行代码:
l = [1,2,3]
def test(a):
if a > 0:
return a
if a > 2:
l.append(4)
test(5)
l仍然等于[1,2,3]
答案 0 :(得分:14)
我会将我的评论扩展到答案。
在所有案件都返回的情况下,这些确实是等同的。在选择它们之间变得重要的是更具可读性。
您的后一个示例使用elif
结构明确声明案例是互斥的,而不是依赖于它们隐含地来自返回的事实。这使得信息更加明显,因此代码更易于阅读,并且不易出错。
比方说,有人决定还有另一个案例:
def example(x):
if x > 0:
return 'positive'
if x == -15:
print("special case!")
if x < 0:
return 'negative'
return 'zero'
突然间,如果用户希望该案例相互排斥,则存在潜在的错误(显然,考虑到该示例,这没有多大意义,但可能在更现实的情况下)。如果使用elif
,则会消除这种歧义,并且在添加代码时添加代码的人员可以看到这种行为,而这些代码在添加代码时可能会看到。
如果我遇到您的第一个代码示例,我可能会认为使用if
而不是elifs
的选择意味着案例不相互排斥,所以改变x
的值可以用来改变if
执行的内容(显然在这种情况下意图是明显的和相互排斥的,但同样,我们谈论的是不太明显的情况 - 并且一致性很好,所以即使在很明显的简单例子中,最好坚持一种方式。)
答案 1 :(得分:4)
检查一下以了解其中的区别:
>>> a = 2
>>> if a > 1: a = a+1
...
>>> if a > 2: a = a+1
...
>>> a
4
与
>>> a = 2
>>> if a > 1: a = a+1
... elif a > 2: a = a+1
...
>>> a
3
第一种情况相当于两个不同的if
带有空else
语句(或想象else: pass
);在第二种情况下,elif
是第一个if
语句的一部分。
答案 2 :(得分:3)
在某些情况下,正确的语义需要elif
。当条件不相互排斥时就是这种情况:
if x == 0: result = 0
elif y == 0: result = None
else: result = x / y
在某些情况下,它是有效的,因为解释器不需要检查所有条件,在您的示例中就是这种情况。如果x为负数,那么为什么要检查正数?在这种情况下,elif
也使代码更具可读性,因为它清楚地表明只会执行一个分支。
答案 3 :(得分:2)
一般情况下(例如您的示例),您始终会使用if..elif
梯形图来明确显示条件是互斥的。它可以防止歧义,错误等。
我可以想到你可能永远不会使用elif
并使用if
的唯一原因是来自前面if
语句(或前一个{{{{{ {1}}语句可能已经改变了条件,从而可能使它不再相互排斥。所以它不再是一个阶梯,只是单独的连接elif
块。 (在单独的块之间留一个空行,以获得良好的风格,并防止有人意外地认为它应该是if(..elif..else)
并且“修复它”
这是一个人为的例子,只是为了证明这一点:
elif
如果第一个if-block应用折扣,你可以看到它可以达到这两个条件,那么我们也会执行第二个,这会打印一条令人困惑的消息,因为我们的原始总数是&gt ; = 10
这里的if total_cost>=10:
if give_shopper_a_random_discount():
print 'You have won a discount'
total_cost -= discount
candidate_prime = True
if total_cost<10:
print 'Spend more than $10 to enter our draw for a random discount'
会阻止这种情况。
但是可能还有其他情况我们希望第二个块运行,即使对于那种情况也是如此。
elif
答案 4 :(得分:0)
elif
效率更高,而且非常合乎逻辑:对于if
,程序必须每次都评估每个逻辑表达式。但在elif
中,并非总是如此。但是,在您的示例中,这种改进非常非常小,可能无法察觉,因为评估x > 0
是最便宜的操作之一。
在使用elif
时,考虑最佳订单也是一个好主意。考虑这个例子:
if (x-3)**3+(x+1)**2-6*x+4 > 0:
#do something 1
elif x < 0:
#do something 2
这里的程序每次都要评估丑陋的表情!但是,如果我们更改顺序:
if x < 0:
#do something 2
elif (x-3)**3+(x+1)**2-6*x+4 > 0:
#do something 1
现在程序将首先检查x&lt; 0(便宜又简单),只有当它不是时,它才会评估更复杂的表达式(顺便说一下,这段代码没有多大意义,它只是一个随机的例子)
此外,perreal说的是什么。
答案 5 :(得分:0)
关于问题的 edit 部分,当您说: “有几个人说,在第一个示例中,两个if语句都总是被求值,对我而言似乎并非如此。”
然后您提供了此示例:
l = [1,2,3]
def test(a):
if a > 0:
return a
if a > 2:
l.append(4)
test(5)
是的,确实列表l
在这种情况下仍将等于[1,2,3]
,这仅是因为您要返回运行块的结果,因为return
语句会导致退出函数,如果您将elif
与return语句一起使用,则会产生相同的结果。
现在尝试使用print
语句而不是return
语句,您将看到第二条if
语句将很好地执行,而4
将执行确实使用l
附加到列表append
。
好吧..如果第一个if
语句更改了第二个if
语句中正在评估的值,该怎么办?
是的,这是另一种情况。例如,假设您有一个变量x
,并且您使用了if
语句来评估实际上改变了x
值的代码块。
现在,如果您使用另一条if
语句来评估相同的变量x
将是错误的,因为您正在考虑将x
的值与其初始值相同,而实际上在执行第一个if
之后更改。因此,您的代码将是错误的。
它经常发生,有时您甚至希望对其进行显式更改。如果那是您希望代码表现出来的方式,那么是的,您应该使用多个if
来完成工作。否则请坚持使用elif
。
在我的示例中,第一个if
块被执行并更改了x
的值,这导致第二个if
评估了不同的x
(因为值已更改)。
这是elif
派上用场的地方,可以防止此类事情的发生,这是使用它的主要好处。
使用elif
而不是多个if
的另一个 secondary 好处是避免混淆和提高代码可读性。
答案 6 :(得分:0)
考虑一下对于寻找简单方法的人:
>>> a = ['fb.com', 'tw.com', 'cat.com']
>>> for i in a:
... if 'fb' in i:
... pass
... if 'tw' in i:
... pass
... else:
... print(i)
<块引用>
输出:
fb.com
cat.com
和
>>> a = ['fb.com', 'tw.com', 'cat.com']
>>> for i in a:
... if 'fb' in i:
... pass
... elif 'tw' in i:
... pass
... else:
... print(i)
<块引用>
输出:
cat.com
'If' 检查第一个条件,然后搜索 elif 或 else,而使用 elif,在 if 之后,它继续检查所有 elif 条件,最后转到 else。 >