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 に答える