2

我有一个元组列表,我需要通过添加两个元素来扩展它,每个元素都来自一个列表。所以我有[(1, 2, 3)]和两个迭代器it1 = (i for i in ['a1', 'a2'])it2 = (i for i in in ['b1', 'b2'])。结果应该是[(1, 2, 3, 'a1', 'b1'), (1, 2, 3, 'a1', 'b2'), (1, 2, 3, 'a2', 'b1'), (1, 2, 3, 'a2', 'b2')]Python:从嵌套迭代器合成列表

如果我使用迭代器,如上所示,它不起作用。但如果我使用它的作品。这里是代码:

def get_iters(): 
    return ((i for i in ['a1', 'a2']), (i for i in ['b1', 'b2'])) 

def get_lists(): 
    return ([i for i in ['a1', 'a2']], [i for i in ['b1', 'b2']]) 

def compose(lst_of_tuples, iter=True): 
    iters = get_iters() if iter else get_lists() 
    for it in iters: 
     lst_of_tuples = [t + (i,) for t in lst_of_tuples for i in it] 
    return lst_of_tuples 

print compose([(1,2,3)], True) 
# WRONG!???? (what happened to the 'a2' part of it?) 
# prints: [(1, 2, 3, 'a1', 'b1'), (1, 2, 3, 'a1', 'b2')] 

print compose([(1,2,3)], False) 
# RIGHT!! prints: [(1, 2, 3, 'a1', 'b1'), (1, 2, 3, 'a1', 'b2'), (1, 2, 3, 'a2', 'b1'), (1, 2, 3, 'a2', 'b2')] 

我想不出为什么会这样。有人可以解释吗?

回答

5

只能在上迭代迭代器件,一次,之后它们将耗尽。

在for循环中第二次循环给定迭代时,不会返回更多元素。

遍历itertools.product()先代替,然后在你的元组的列表来生成输出中:

from itertools import product 

def compose(lst_of_tuples, iter=True): 
    iters = get_iters() if iter else get_lists() 
    return [t + i for i in product(*get_iters()) for t in lst_of_tuples] 

这将产生:

>>> print compose([(1,2,3)], True) 
[(1, 2, 3, 'a1', 'b1'), (1, 2, 3, 'a1', 'b2'), (1, 2, 3, 'a2', 'b1'), (1, 2, 3, 'a2', 'b2')] 
>>> print compose([(1,2,3)], False) 
[(1, 2, 3, 'a1', 'b1'), (1, 2, 3, 'a1', 'b2'), (1, 2, 3, 'a2', 'b1'), (1, 2, 3, 'a2', 'b2')] 
+0

确定。我现在明白了。迭代器(it1或it2)在迭代了'lst_of_tuples'的第一个元素后用完。所以代码只能用于第一个元素。如果我在lst_of_tuples中为t做了[t +(i,),那么它就起作用了。感谢itertool.product的想法 - 整洁。 – dividebyzero