如何在生成器中创建生成器-Python

时间:2018-07-10 20:31:01

标签: python generator

如果我创建了一个列表:

_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

并尝试使用生成器获取每个值<= 6:

test = next(i for i in a for a in _list if i <= 6)

(这不起作用↑↑↑↑↑)

如何使用生成器遍历列表中的列表?如果这不可能,我可以用什么方法代替它?

我在这里看过: python generator of generators?,但找不到答案...

5 个答案:

答案 0 :(得分:7)

使用内置模块chain中的itertools

from itertools import chain

_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

print(list(i for i in chain.from_iterable(_list) if i <= 6))

输出:

  

[1、2、3、4、5、6]

itertools.chain的作用是什么?根据{{​​3}}:

  

制作一个迭代器,该迭代器从第一个迭代器返回元素,直到   耗尽,然后进行下一个迭代,直到所有   可迭代的东西用尽了。用于将连续序列视为   单个序列。

答案 1 :(得分:2)

在这种情况下,

无需创建generator的生成器。只需在一个生成器中创建一个double for循环即可(将列表展平,然后测试元素值):

_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

gen = (x for sublist in _list for x in sublist if x <= 6)

这种双重for理解语法需要一些习惯,理解通常以“相反的方式”编写,但在循环情况下则不需要,因此会造成混乱。更一般的形式是:

(expression(item) for sublist in input_list for item in sublist if condition(item))

然后获取第一个匹配元素:

print(next(gen,None))  # None is printed if there's no matching element

(要获取所有元素,当然必须在gen上进行迭代,next提供了“下一个”值,就像在生成器上“手动”进行迭代一样)

答案 2 :(得分:0)

要在同一个生成器中嵌套两个fors,必须颠倒顺序

test = next(i for a in _list for i in a if i <= 6)

答案 3 :(得分:0)

您可以结合使用itertools.takewhileitertools.chain来创建符合您要求的迭代器

>>> from itertools import chain, takewhile
>>> itr = takewhile(lambda i: i<=6, chain(*_list))
>>> print (list(itr))
[1, 2, 3, 4, 5, 6]

答案 4 :(得分:-1)

>>> t = (i for a in _list for i in a if i <= 6)
>>> next(t)
1
>>> next(t)
2
>>> next(t)
3
>>> next(t)
4
>>> next(t)
5
>>> 

使用list将迭代器转换为列表

>>> t = (i for a in _list for i in a if i <= 6)
>>> list(t)
[1, 2, 3, 4, 5, 6]