何时在 python 中使用 if vs elif

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22782785/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 01:40:01  来源:igfitidea点击:

when to use if vs elif in python

pythonconditionalidioms

提问by Sean Geoffrey Pietz

If I have a function with multiple conditional statements where every branch gets executed returns from the function. Should I use multiple if statements, or if/elif/else? For example, say I have a function:

如果我有一个带有多个条件语句的函数,其中每个分支都被执行,从函数返回。我应该使用多个 if 语句还是 if/elif/else?例如,假设我有一个函数:

def example(x):
    if x > 0:
        return 'positive'
    if x < 0:
        return 'negative'
    return 'zero'

Is it better to write:

是否更好地写:

def example(x):
    if x > 0:
        return 'positive'
    elif x < 0:
        return 'negative'
    else:
        return 'zero'

Both have the same outcome, but is one more efficient or considered more idiomatic than the other?

两者都有相同的结果,但是一个比另一个更有效或被认为更惯用吗?

Edit:

编辑:

A couple of people have said that in the first example both if statements are always evaluated, which doesn't seem to be the case to me

有几个人说过,在第一个例子中,两个 if 语句总是被评估,这对我来说似乎并非如此

for example if I run the code:

例如,如果我运行代码:

l = [1,2,3]

def test(a):
    if a > 0:
        return a
    if a > 2:
        l.append(4)

test(5)

l will still equal [1,2,3]

l 仍将等于 [1,2,3]

采纳答案by Gareth Latty

I'll expand out my comment to an answer.

我会将我的评论扩展到一个答案。

In the case that all cases return, these are indeed equivalent. What becomes important in choosing between them is then what is more readable.

在所有情况都返回的情况下,这些确实是等价的。在它们之间进行选择变得重要的是什么更具可读性。

Your latter example uses the elifstructure to explicitly state that the cases are mutually exclusive, rather than relying on the fact they are implicitly from the returns. This makes that information more obvious, and therefore the code easier to read, and less prone to errors.

您的后一个示例使用该elif结构来明确说明案例是互斥的,而不是依赖于它们隐式来自返回的事实。这使得该信息更加明显,因此代码更易于阅读,并且更不容易出错。

Say, for example, someone decides there is another case:

比如说,有人认为还有另外一种情况:

def example(x):
    if x > 0:
        return 'positive'
    if x == -15:
        print("special case!")
    if x < 0:
        return 'negative'
    return 'zero'

Suddenly, there is a potential bug if the user intended that case to be mutually exclusive (obviously, this doesn't make much sense given the example, but potentially could in a more realistic case). This ambiguity is removed if elifs are used and the behaviour is made visible to the person adding code at the level they are likely to be looking at when they add it.

突然间,如果用户希望这种情况相互排斥,就会出现一个潜在的错误(显然,鉴于这个例子,这没有多大意义,但在更现实的情况下可能会如此)。如果使用elifs 并且行为对添加代码的人在他们添加代码时他们可能会查看的级别可见,则这种歧义将被消除。

If I were to come across your first code example, I would probably assume that the choice to use ifs rather than elifsimplied the cases were notmutually exclusive, and so things like changing the value of xmight be used to change which ifs execute (obviously in this case the intention is obvious and mutually exclusive, but again, we are talking about less obvious cases - and consistency is good, so even in a simple example when it is obvious, it's best to stick to one way).

如果我遇到你的第一个代码示例,我可能会假设使用ifs 而不是elifs暗示案例的选择不是相互排斥的,因此诸如更改 的值之类的事情x可能会用于更改 whichif的执行(显然在在这种情况下,意图是明显且相互排斥的,但同样,我们谈论的是不太明显的情况 - 而且一致性很好,所以即使在一个简单的例子中,当它很明显时,最好坚持一种方式)。

回答by perreal

In some cases, elifis required for correct semantics. This is the case when the conditions are not mutually exclusive:

在某些情况下,elif需要正确的语义。当条件不相互排斥时就是这种情况:

if x == 0:   result = 0
elif y == 0: result = None
else:        result = x / y

In some cases it is efficient because the interpreter doesn't need to check all conditions, which is the case in your example. If x is negative then why do you check the positive case? An elifin this case also makes code more readable as it clearly shows only a single branch will be executed.

在某些情况下,它是有效的,因为解释器不需要检查所有条件,在您的示例中就是这种情况。如果 x 是负数,那么为什么要检查正数呢?elif在这种情况下,An还使代码更具可读性,因为它清楚地表明只会执行一个分支。

回答by Dunno

elifis a bit more efficient, and it's quite logical: with ifs the program has to evaluate each logical expression every time. In elifs though, it's not always so. However, in your example, this improvement would be very, very small, probably unnoticeable, as evaluating x > 0is one of the cheapest operations.

elif效率更高,而且非常合乎逻辑:使用ifs 程序每次都必须评估每个逻辑表达式。但在elifs 中,情况并非总是如此。但是,在您的示例中,这种改进将非常非常小,可能不会引起注意,因为评估x > 0是最便宜的操作之一。

When working with elifs it's also a good idea to think about the best order. Consider this example:

使用elifs 时,考虑最佳顺序也是一个好主意。考虑这个例子:

if (x-3)**3+(x+1)**2-6*x+4 > 0:
    #do something 1
elif x < 0:
    #do something 2

Here the program will have to evaluate the ugly expression every time! However, if we change the order:

这里程序每次都必须评估丑陋的表达式!但是,如果我们更改顺序:

if x < 0:
   #do something 2
elif (x-3)**3+(x+1)**2-6*x+4 > 0:
   #do something 1

Now the program will first check if x < 0 (cheap and simple) and only if it isn't, will it evaluate the more complicated expression (btw, this code doesn't make much sense, it's just a random example)

现在程序将首先检查 x < 0 (便宜且简单),如果不是,它会评估更复杂的表达式(顺便说一句,这段代码没有多大意义,这只是一个随机示例)

Also, what perreal said.

另外,perreal 所说的。

回答by marco

Check this out to understand the difference:

检查这个以了解差异:

>>> a = 2
>>> if a > 1: a = a+1
...
>>> if a > 2: a = a+1
...
>>> a
4

versus

相对

>>> a = 2
>>> if a > 1: a = a+1
... elif a > 2: a = a+1
...
>>> a
3

The first case is equivalent to two distinct if's with empty elsestatements (or imagine else: pass); in the second case elifis part of the first ifstatement.

第一种情况相当于两个不同if的带有空else语句(或想象else: pass);在第二种情况下elif是第一个if语句的一部分。

回答by smci

In general (e.g. your example), you would always use an if..elifladder to explicitly show the conditions are mutually-exclusive. It prevents ambiguity, bugs etc.

一般来说(例如您的示例),您将始终使用if..elif梯子来明确显示条件是互斥的。它可以防止歧义、错误等。

The only reason I can think of that you might ever not use elifand use ifinstead would be if the actions from the body of the preceding ifstatement (or previous elifstatements) might have changed the condition so as to potentially make it no longer mutually exclusive. So it's no longer really a ladder, just separate concatenated if(..elif..else)blocks. (Leave an empty line between the separate blocks, for good style, and to prevent someone accidentally thinking it should have been elifand 'fixing' it)

我能想到的你可能永远不会使用elif和使用的唯一原因if是,如果来自前一条if语句(或前elif一条语句)主体的操作可能已经改变了条件,从而可能使其不再相互排斥。所以它不再是真正的梯子,只是单独的连接if(..elif..else)块。(在单独的块之间留一个空行,以获得良好的风格,并防止有人不小心认为它应该是elif并“修复”它)

Here's a contrived example, just to prove the point:

这是一个人为的例子,只是为了证明这一点:

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  to enter our draw for a random discount'

You can see it's possible to hit both conditions, if the first if-block applies the discount, so then we also execute the second, which prints a message which would be confusing since our original total had been >=10.

您可以看到有可能同时满足这两个条件,如果第一个 if 块应用了折扣,那么我们也执行第二个,它会打印一条消息,这会令人困惑,因为我们的原始总数 >=10。

An elifhere would prevent that scenario. But there could be other scenarios where we want the second block to run, even for that scenario.

elif这里可以防止出现这种情况。但是可能还有其他场景我们希望第二个块运行,即使是在那个场景中也是如此。

if total_cost<10:
    <some other action we should always take regardless of original undiscounted total_cost>

回答by Fouad Boukredine

In regards to the editportion of your question when you said: "A couple of people have said that in the first example both if statements are always evaluated, which doesn't seem to be the case to me"

关于你的问题的编辑部分,当你说:“有几个人说过,在第一个例子中,两个 if 语句总是被评估,这对我来说似乎并非如此”

And then you provided this example:

然后你提供了这个例子:

l = [1,2,3]

def test(a):
    if a > 0:
        return a
    if a > 2:
        l.append(4)

test(5)

Yes indeed the list lwill still equal [1,2,3]in this case, ONLY because you're RETURNING the result of running the block, because the returnstatement leads to exiting the function, which would result in the same thing if you used elifwith the return statement.

是的,在这种情况下,列表确实l仍然相等[1,2,3],只是因为您正在返回运行块的结果,因为该return语句导致退出函数,如果您elif与 return 语句一起使用,这将导致相同的结果。

Now try to use the printstatement instead of the returnone, you'll see that the 2nd ifstatement will execute just fine, and that 4will indeed be appended to the list lusing append.

现在尝试使用该print语句而不是第return一个,您会看到第二个if语句将执行得很好,并且4确实会l使用append.

Well.. now what if the first ifstatement changes the value of whatever is being evaluated in the 2nd ifstatement?

好吧..现在如果第一个if语句改变了第二个if语句中正在评估的值怎么办?

And yes that's another situation. For instance, say you have a variable xand you used ifstatement to evaluate a block of code that actually changed the xvalue. Now, if you use another ifstatement that evaluates the same variable xwill be wrong since you're considering xvalue to be the same as its initial one, while in fact it was changed after the first ifwas executed. Therefore your code will be wrong.

是的,这是另一种情况。例如,假设您有一个变量,x并且您使用if语句来评估实际更改该x值的代码块。现在,如果您使用另一个if评估相同变量的语句x将是错误的,因为您认为xvalue 与其初始值相同,而实际上它在第一个if执行后已更改。因此,您的代码将是错误的。

It happens pretty often, and sometimes you even want it explicitly to be changed. If that's how you want your code to behave, then yes you should use multiple if's which does the job well. Otherwise stick to elif.

它经常发生,有时您甚至希望明确更改它。如果这就是您希望代码的行为方式,那么是的,您应该使用 multipleif来很好地完成工作。否则坚持elif

In my example, the 1st ifblock is executed and changed the value of x, which lead to have the 2nd ifevaluates a different x(since its value was changed).

在我的示例中,第一个if块被执行并更改了 的值x,这导致第二个if评估不同x(因为它的值已更改)。

That's where elifcomes in handy to prevent such thing from happening, which is the primary benefit of using it. The other secondarygood benefit of using elifinstead of multiple if's is to avoid confusion and better code readability.

这就是elif防止此类事情发生的地方,这是使用它的主要好处。使用而不是 multiple的另一个次要好处是避免混淆和更好的代码可读性。elifif