如果我创建了一个列表:
_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?,但找不到答案...
答案 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.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]
答案 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]