Python在列表推导中允许“if
”条件,例如:
[l for l in lines if l.startswith('example')]
常规“for
”循环中缺少此功能,因此没有:
for line in lines if line.startswith('example'):
statements
需要评估循环中的条件:
for line in lines:
if line.startswith('example'):
statements
或嵌入生成器表达式,如:
for line in [l for l in lines if l.startswith('example')]:
statements
我的理解是否正确?是否有比上面列出的方法更好或更pythonic的方式来实现在for循环中添加条件的相同结果?
请注意选择“行”作为示例,任何集合或生成器都可以在那里。
答案 0 :(得分:2)
其他答案和评论提出了一些不错的想法,但我认为this recent discussion on Python-ideas和its continuation是这个问题的最佳答案。
总结一下:过去已经讨论过这个想法,考虑到以下因素,这些好处似乎不足以激发语法变化:
语言复杂性增加及对学习曲线的影响
所有实施中的技术变更:CPython,Jython,Pypy ..
极端使用synthax可能导致的奇怪情况
人们似乎高度考虑的一点是避免使Perl相似的复杂性损害可维护性。
This message和this one很好地总结了可能的替代方案(几乎已经在本页中出现)到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()
答案 1 :(得分:1)
也许不是Pythonic,但你可以filter
这些线。
for line in filter(lambda l: l.startswith('example'), lines):
print(line)
你可以定义自己的过滤功能,当然,如果这个lambda困扰你,或者你想要更复杂的过滤。
def my_filter(line):
return line.startswith('example') or line.startswith('sample')
for line in filter(my_filter, lines):
print(line)
我会说在循环中具有条件是更好的,因为当你迭代这些行时你没有在内存中维护“过滤”列表。
所以,那只是
for line in file:
if not my_filter(line):
continue
# statements
答案 2 :(得分:0)
并不是缺少这个功能,除了一些特殊情况外,我想不出有什么方法可以做到。 (l for l in lines if l.startswith('example'))
是生成器对象,l
变量是该对象的本地变量。 for
只能看到生成器的__next__
方法返回的内容。
for
非常不同,因为生成器的结果需要绑定到调用者范围内的变量。你可以写
for line in (line for line in lines if l.startswith('example')):
foo(line)
安全,因为这两个line
的范围不同。
此外,生成器不必仅返回其局部变量。它可以评估任何表达式。你会如何做到这一点?
for line in (foo(line)+'bar' for line in lines if line.startswith('example')):
statements
假设您有一个列表列表
for l in (l[:] for l in list_of_lists if l):
l.append('modified')
不应附加到原始列表中。
答案 3 :(得分:0)
是否有比上面列出的更好或更pythonic方式来实现在for循环中添加条件的相同结果?
不,没有,也不应该; 这就是为什么列表理解首先来到这里的理由。来自corresponding PEP:
列表推导提供了一种更简洁的方式,可以在当前使用
map()
和filter()
和/或嵌套循环的情况下创建列表。
列表推导构成了嵌套for
,if
s的替代方案;你为什么要替代替代方案?
如果您需要将if
与for
一起使用,则将其嵌入其中,如果您不想这样做,则使用列表推导。 Flat优于嵌套 ,但 可读性计数;允许if
会导致难看的长丑线在视觉上解析。