繁体   English   中英

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

[英]How do I create a generator within a generator- Python

如果我创建了一个列表:

_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 generators of generators? ,但找不到答案...

使用内置模块itertools chain

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是做什么的? 根据手册页

创建一个迭代器,该迭代器从第一个可迭代对象返回元素,直到耗尽为止,然后继续进行下一个可迭代对象,直到所有可迭代对象都耗尽为止。 用于将连续序列视为单个序列。

在这种情况下,您无需创建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提供“ next”值,就像您在生成器上“手动”进行迭代一样)

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

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

您可以结合使用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]
>>> 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]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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