Python 的越来越多的功能都转向“惰性执行”,例如生成器表达式和其他类型的迭代器。然而,有时我发现自己想要运行一行“for”循环,只是为了执行一些操作。
要使循环真正执行,最具 Python 特色的事情是什么?
例如:
a = open("numbers.txt", "w") (a.write ("%d " % i) for i in xrange(100)) a.close()
不是实际的代码,但你明白我的意思。如果我使用列表生成器,则会产生副作用,即创建一个填充有“无”的 N 长度列表。
目前我的做法是使用表达式作为调用“any”或“all”的参数。但我想找到一种不依赖于循环中执行的表达式结果的方法 - “any”和“all”都可以停止依赖于所求表达式的结果。
需要明确的是,这些是我已经知道的方法,每种方法都有其缺点:
[a.write ("%d " % i) for i in xrange(100))] any((a.write ("%d " % i) for i in xrange(100))) for item in (a.write ("%d " % i) for i in xrange(100)): pass
为了在不创建不必要数据结构的情况下执行循环,最“Pythonic”的方法是使用显式循环。但如果你希望一种更简洁的方法而避免副作用的列表生成式或过于冗长的显式循环,可以考虑以下方式:
collections.deque
collections.deque 提供了一个很好的方式通过“消费”生成器表达式来执行操作而不创建额外数据。
from collections import deque a = open("numbers.txt", "w") deque((a.write("%d " % i) for i in range(100)), maxlen=0) a.close()
deque
maxlen=0
for
这是最简单、直观的方法。
a = open("numbers.txt", "w") for i in range(100): a.write("%d " % i) a.close()
any
all
虽然这是一个常见的技巧,但它依赖于表达式返回的布尔值,这可能不直观。
a = open("numbers.txt", "w") any(a.write("%d " % i) for i in range(100)) # 或者 all() a.close()
True
False
list
这会创建一个包含 None 的列表,浪费内存。
None
a = open("numbers.txt", "w") [a.write("%d " % i) for i in range(100)] a.close()
如果代码的可读性优先,直接使用显式的 for 循环。如果你追求简洁和 Pythonic 的方法,collections.deque 是一个值得推荐的解决方案。