让我们以 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
一种方法实际上比另一种方法更好/更有效,还是这只是打字的偏好?
在这种特殊情况下,除了可读性之外,无论您将否定放在 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()