首页 > 解决方案 > 可以使带有 if 的 for 循环像带有 elif 和 else 分支的 if 一样工作吗?

问题描述

我有一个像这样的代码:

if 'x' in longstr:
    longstr = longstr.replace('x', '')
elif 'y' in longstr:
    longstr = longstr.replace('y', '')
elif 'z' in longstr:
    longstr = longstr.replace('z', '')
else:
    longstr = longstr.replace('foo', '')

如果我想改用for循环:

for char in ['x','y','z']:
    if char in longstr:
        longstr = longstr.replace(str, '')
        break

如何替换上面示例else:中的最终/一般情况if..elif..elseelse: longstr = longstr.replace('xyz', ''))?

最重要的是,这两种形式中哪一种表现更好?

标签: pythonpython-3.xperformancefor-loopif-statement

解决方案


只需在循环中添加一个else:套件:for

for char in ['x','y','z']:
    if char in longstr:
       longstr = longstr.replace(char, '')
       break
else:
    longstr = longstr.replace('xyz', '')

循环中的else套件for仅在for循环结束而没有提前结束时执行break。请参阅for声明文档

当项目用尽[...]时,子句中的套件else(如果存在)将被执行,并且循环终止。

在第一个套件中执行的break语句终止循环而不执行该else子句的套件。

要查看哪个性能更好,您必须使用timeit. 但是,除非您在紧密循环中执行关键代码部分,否则请坚持使用,if...elif...else因为该for...else组合并不为人所知,并且会使许多程序员不了解语义而摸不着头脑。此外,对于您的玩具示例,无论如何您都会在if测试或for循环中使用正则表达式。

定时这两个简单的例子:

>>> from timeit import Timer
>>> def example1(longstr):
...     if 'x' in longstr:
...         longstr = longstr.replace('x', '')
...     elif 'y' in longstr:
...         longstr = longstr.replace('y', '')
...     elif 'z' in longstr:
...         longstr = longstr.replace('z', '')
...     else:
...         longstr = longstr.replace('foo', '')
...
>>> def example2(longstr):
...     for char in ['x','y','z']:
...         if char in longstr:
...            longstr = longstr.replace(char, '')
...            break
...     else:
...         longstr = longstr.replace('xyz', '')
...
>>> from string import ascii_lowercase
>>> from random import choice
>>> teststring = ''.join([choice(ascii_lowercase) for _ in range(10000)])
>>> for ex in (example1, example2):
...     count, total = Timer('ex(s)', 'from __main__ import teststring as s, ex').autorange()
...     print(f'{ex.__name__}: {total/count * 1000000}µs')
...
example1: 15.999997949984389µs
example2: 16.788980951241683µs

表明它们之间只有 1.8微秒。如果我重新运行样本几次,一个或另一个示例会以类似的极小幅度获胜。这并不能真正使一个或另一个最快,所以在这种情况下你可以认为它们是相等的。

但是,如果您确实需要对此类部分进行微优化,则需要自己安排时间。


推荐阅读