将生成器表达式嵌套在python函数调用的参数列表中

时间:2009-10-25 13:44:38

标签: python generator list-comprehension

我喜欢使用以下习惯用法将列表组合在一起,有时候:

>>> list(itertools.chain(*[[(e, n) for e in l] for n, l in (('a', [1,2]),('b',[3,4]))]))
[(1, 'a'), (2, 'a'), (3, 'b'), (4, 'b')]

(我知道有更简单的方法来获得这个特定的结果,但是当你想要迭代列表列表中的元素或类似的东西时,它会派上用场。麻烦的是,当你使用生成器时表达式,这容易出错。例如

>>> list(itertools.chain(*(((e, n) for e in l) for n, l in (('a', [1,2]),('b',[3,4])))))
[(1, 'b'), (2, 'b'), (3, 'b'), (4, 'b')]

这里发生的是内部生成器表达式作为参数传递给itertools.chain,所以在它们被评估时,外部生成器表达式已经完成,并且n被修复为最终价值'b'。我想知道是否有人想到了避免这种错误的方法,除了“不要这样做。”

3 个答案:

答案 0 :(得分:6)

嵌套列表理解不会更合适吗?

>>> tt = (('a', [1,2]),('b',[3,4]))
>>> [(s, i) for i, l in tt for s in l]
[(1, 'a'), (2, 'a'), (3, 'b'), (4, 'b')]

答案 1 :(得分:2)

你的方法几乎可以工作,你只需要压平发电机。了解for e in l如何移至最右侧

>>> list(itertools.chain((e, n) for n, l in (('a', [1,2]),('b',[3,4])) for e in l ))
[(1, 'a'), (2, 'a'), (3, 'b'), (4, 'b')]

以下是使用itertools.product

执行相同操作的方法
>>> X=itertools.chain(*(itertools.product(*i[::-1]) for i in (('a', [1,2]),('b',[3,4]))))
>>> print list(X)
[(1, 'a'), (2, 'a'), (3, 'b'), (4, 'b')]

或者如果你被允许切换元组

>>> X=itertools.chain(*(itertools.product(*i) for i in (([1,2],'a'),([3,4],'b'))))
>>> print list(X)
[(1, 'a'), (2, 'a'), (3, 'b'), (4, 'b')]

答案 2 :(得分:0)

我要建议

data = (('a', [1,2]), ('b', [3,4]))

result = []
for letter, numbers in data:
     for number in numbers:
         result.append((number, letter))

它比您的解决方案系列更具可读性。花哨并不是件好事。