[英]python list comprehension on generator with if condition
我試圖用生成器上的if條件執行列表理解,但是代碼陷入了for循環。
import time
def gen():
a = 0
b = 1
while True:
a += 1
b += 1
yield a, b
init_time = time.time()
m = [{'a': x, 'b': y} for x, y in gen() if time.time() - init_time < 3]
我意識到這是因為gen()
將無限返回,並且將繼續執行直到gen()
可迭代,還有其他方法嗎?
列表推導中的if
條件不是停止條件,而是一個filter 。 如所寫,3秒鍾后,它將僅開始忽略來自生成器的配對,並且永遠不會返回到目前為止的列表。
另一個問題是列表推導當前位於生成器內部,這(在非常特殊的情況下除外)不是生成器使用列表推導的方式。 列表理解對生成器生成的對象進行迭代,而與生成器的定義無關。
最后,您的生成器是infinite 。 盡管無限生成器是完全有效且非常有用的,但它們無法傳遞給列表推導,因為列表推導要消耗整個生成器,按照定義,無限生成器是不可能的。 但是,可以編寫適應無限生成器的有限生成器,並在達到條件時停止。 itertools.islice
是標准庫中此類包裝器的示例,但是您可以輕松編寫自己的包裝器。 基於時間的包裝器可能如下所示:
def iter_until(tm, iterable):
t0 = time.time()
for val in iterable:
yield val
if time.time() - t0 > tm:
break
此包裝器可以輕松地與原始無限生成器組合,並用於列表比較:
def gen():
a = 0
b = 1
while True:
a += 1
b += 1
yield a, b
m = [{'a': x, 'b': y} for x, y in iter_until(3, gen())]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.