Python if 语句中条件的顺序有区别吗?

问题描述 投票:0回答:1

让我们以 Leetcode 问题为例,“第一个字母出现两次”(https://leetcode.com/problems/first-letter-to-appear-twice/)。我提出的一般解决方案是迭代字符串,将值存储在“seen”列表中,如果下一个值已经在“seen”列表中,则返回该值。

所以如果我有一些像这样的代码:

class Solution:
    def repeatedCharacter(self, s: str) -> str:
        seen = []
        for i in s:
            if i in seen:
                return i
            else:
                seen.append(i)
        

与此有什么不同(在时间或记忆方面):

class Solution:
    def repeatedCharacter(self, s: str) -> str:
        seen = []
        for i in s:
            if i not in seen:
                seen.append(i)
            else:
                return i
        

一种方法实际上比另一种方法更好/更有效,还是这只是打字的偏好?

python arrays for-loop if-statement optimization
1个回答
0
投票

在这种特殊情况下,除了可读性之外,无论您将否定放在 if 还是 else 中,性能或我所知道的任何其他指标都没有区别。

也就是说,从一般意义上来说,if/elif/else 结构中的条件顺序可能会产生很大的差异。考虑以下几点:

if some_expensive_function():
    do_some_code_branch1()
elif some_flag:
    do_some_code_branch2()
else:
    return

在这种情况下,将 some_expense_function() 放在 if 开头可确保它始终被执行/检查。将顺序颠倒过来会更有效:

if some_flag:
    do_some_code_branch2()
elif some_expensive_function():
    do_some_code_branch1()
else:
    return

因为这样,简单的布尔标志检查将首先进行,如果它解析为 True,则 some_expense_function 根本不会被调用,因为 if/elif/else 结构从上到下检查每个条件,直到一个为 True,并且然后爆发而不执行其余部分。同样的原理也适用于复合条件:

if some_flag or some_expensive_function():
    pass # Do something

平均而言,上面的方法比下面的方法要高效得多:

if some_expensive_function() or some_flag:
    pass # Do something

顺便说一句,这也是产生许多优雅的单行作业的相同思路,例如:

instance = element or db.lookup_element()

上面替换了显式格式,这相当不那么Pythonic:

if element:
    instance = element
else:
    instance = db.lookup_element()
© www.soinside.com 2019 - 2024. All rights reserved.