1

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

>>> 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'. 我想知道除了“不要那样做”之外,是否有人想过避免这种错误的方法。

4

3 回答 3

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')]
于 2009-10-25T14:12:29.897 回答
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')]
于 2009-10-25T14:49:08.573 回答
0

我要建议

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

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

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

于 2009-10-25T15:47:19.997 回答