从python3中的延迟生成器中获取N个项目的简明方法?

时间:2017-07-03 14:54:33

标签: python generator

我有一个懒惰的生成器,我想拿N个项目并将它们放在一个列表中。有没有简洁的方法(类似于列表理解风格)而不使用for循环并手动将每个项目附加到列表中?

我的问题与提出的重复问题不同,因为它涉及生成器(而且你不能切片生成器)并且必须满足条件。

这就是我现在正在做的事情:

    my_list = []
    counter = 0
    for item in my_generator():
        if counter == 10:
            break           
        if condition(item):
            my_list.append(item)
            counter += 1

2 个答案:

答案 0 :(得分:0)

使用itertools.islice()函数的简短解决方案:

my_list = list(itertools.islice(my_generator, 0, 10))

https://docs.python.org/3.6/library/itertools.html?highlight=itertools#itertools.islice

答案 1 :(得分:0)

可能有点难看但是使用列表理解来从你的生成器中获取n个项目,然后在外部列表理解中过滤并递归

def takeN(gen, func, n, items=list()): 
    if len(items) == n:
        return items
    return takeN(gen, func, n,
                 items + [fgen 
                          for fgen in [next(gen) for i in range(n-len(items))]
                                   if func(fgen) == True])

my_gen = (i for i in range(1,100))

takeN(my_gen, lambda x: x%3 == 0, 7)
Out[89]: [3, 6, 9, 12, 15, 18, 21]

takeN(my_gen, lambda x: x%3 == 0, 7)
Out[90]: [24, 27, 30, 33, 36, 39, 42]

takeN(my_gen, lambda x: x%2 == 0, 12)
Out[91]: [44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66]

我想尝试递归,但非递归可能更快:

def takeN(gen, func, n):
    items=list() 
    while len(items) != n:
        items += [fgen for fgen in [next(gen) for i in range(n-len(items))]
                                if func(fgen) == True]
    return items