web-dev-qa-db-ja.com

リスト内包表記の二重反復

Pythonでは、リスト内包表記に複数の反復子を含めることができます。

[(x,y) for x in a for y in b]

いくつかの適切なシーケンスaおよびbに対して。 Pythonのリスト内包表記のネストされたループセマンティクスを知っています。

私の質問は、内包表記の1つのイテレーターが他のイテレーターを参照できますか?言い換えれば、次のようなものがありますか?

[x for x in a for a in b]

外側のループの現在の値は内側の反復子ですか?

例として、ネストされたリストがある場合:

a=[[1,2],[3,4]]

この結果を達成するためのリスト内包表記はどうなるでしょうか:

[1,2,3,4]

? (理解の答えのみをリストしてください。これは私が知りたいことですから)。

189
ThomasH

ああ、私はアンサーを見つけたと思います。どのループが内側で、どのループが外側であるかについて十分に注意していませんでした。リストの内包表記は次のようになります。

[x for b in a for x in b]

目的の結果を取得するために、はい、1つの現在の値を次のループの反復子にできます。

108
ThomasH

自分の提案で質問に答えるには:

>>> [x for b in a for x in b] # Works fine

リストの理解の答えを求めている間、素晴らしいitertools.chain()を指摘しましょう:

>>> from itertools import chain
>>> list(chain.from_iterable(a))
>>> list(chain(*a)) # If you're using python < 2.6
143
Cide

a,b,x,yは私にとってあまり意味がないので、これが他の人の助けになることを願っています!文章でいっぱいのテキストがあり、単語の配列が必要だとします。

# Without list comprehension
list_of_words = []
for sentence in text:
    for Word in sentence:
       list_of_words.append(Word)
return list_of_words

リストの理解は、コードを水平方向に引き伸ばすことと考えるのが好きです。

以下に分割してみてください。

# List Comprehension 
[Word for sentence in text for Word in sentence]
122
Skam

イテレータの順序は直感に反するように見える場合があります。

例:[str(x) for i in range(3) for x in foo(i)]

それを分解しましょう:

def foo(i):
    return i, i + 0.5

[str(x)
    for i in range(3)
        for x in foo(i)
]

# is same as
for i in range(3):
    for x in foo(i):
        yield str(x)
40
Dima Tisnek

ThomasHはすでに良い答えを追加していますが、何が起こるかを示したいと思います。

>>> a = [[1, 2], [3, 4]]
>>> [x for x in b for b in a]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined

>>> [x for b in a for x in b]
[1, 2, 3, 4]
>>> [x for x in b for b in a]
[3, 3, 4, 4]

Pythonはリストの内包表記を左から右に解析すると思います。つまり、最初に発生するforループが最初に実行されます。

これの2番目の「問題」は、bがリストの理解から「漏れる」ことです。リストの理解が最初に成功した後b == [3, 4]

18
Martin Thoma

多次元配列を保持する場合は、配列ブラケットをネストする必要があります。すべての要素に1つが追加される以下の例を参照してください。

>>> a = [[1, 2], [3, 4]]

>>> [[col +1 for col in row] for row in a]
[[2, 3], [4, 5]]

>>> [col +1 for row in a for col in row]
[2, 3, 4, 5]
8
steven

さらに、現在アクセスされている入力リストのメンバーに同じ変数を使用することもできますandこのメンバー内の要素に。ただし、これにより、さらに(リスト)がわかりにくくなる場合があります。

input = [[1, 2], [3, 4]]
[x for x in input for x in x]

最初にfor x in inputが評価されて、入力の1つのメンバーリストに至り、次にPythonが2番目の部分for x in xをウォークスルーし、その間にx値が現在の要素によって上書きされますitアクセスしている場合、最初のxは返されるものを定義します。

3
simP

これはわかりやすいと思う

[row[i] for row in a for i in range(len(a))]

result: [1, 2, 3, 4]
3
Miao Li