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