繁体   English   中英

带有if条件的生成器上的python列表理解

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM