for循环中的复合条件

Pin*_*tun 5 python syntax for-loop list-comprehension generator

Python允许if列表推导中的" "条件,例如:

[l for l in lines if l.startswith('example')]
Run Code Online (Sandbox Code Playgroud)

常规" for"循环中缺少此功能,因此在没有:

for line in lines if line.startswith('example'):
    statements
Run Code Online (Sandbox Code Playgroud)

一个人需要评估循环中的条件:

for line in lines:
    if line.startswith('example'):
        statements
Run Code Online (Sandbox Code Playgroud)

或嵌入生成器表达式,如:

for line in [l for l in lines if l.startswith('example')]:
    statements
Run Code Online (Sandbox Code Playgroud)

我的理解是否正确?是否有比上面列出的更好或更pythonic方式来实现在for循环中添加条件的相同结果?

请注意选择"行"作为示例,任何集合或生成器都可以在那里.

Pin*_*tun 1

一些不错的想法来自其他答案和评论,但我认为最近关于 Python 想法及其延续的讨论是这个问题的最佳答案。

总结一下:这个想法过去已经讨论过,考虑到以下因素,其好处似乎不足以推动语法更改:

  • 语言复杂性增加并影响学习曲线

  • 所有实现中的技术更改:CPython、Jython、Pypy..

  • 极端使用合成器可能会导致奇怪的情况

人们似乎高度考虑的一点是避免带来与 Perl 类似的复杂性,从而损害可维护性。

此消息此消息很好地总结了 for 循环中复合 if 语句的可能替代方案(几乎也已出现在本页中):

# nested if
for l in lines:
    if l.startswith('example'):
        body

# continue, to put an accent on exceptional case
for l in lines:
    if not l.startswith('example'):
        continue
    body

# hacky way of generator expression
# (better than comprehension as does not store a list)
for l in (l for l in lines if l.startswith('example')):
    body()

# and its named version
def gen(lines):
    return (l for l in lines if l.startswith('example'))
for line in gen(lines):
    body

# functional style
for line in filter(lambda l: l.startswith('example'), lines):
    body()
Run Code Online (Sandbox Code Playgroud)