2013-10-21 6 views
9
>>> my_list = [[[[1, 2, 3], [4, 5, 6], ]]] 
>>> [a for d in my_list for c in d for b in c for a in b] 
[1, 2, 3, 4, 5, 6] 

は左から右から読んだとき、この構文は、後方思わなぜPythonのリストの理解は逆順になりますか?

>>> my_list = [[[[1, 2, 3], [4, 5, 6], ]]] 
>>> new_list = [] 
>>> for d in my_list: 
...  for c in d: 
...   for b in c: 
...    for a in b: 
...     new_list.append(a) 
... print(new_list): 
[1, 2, 3, 4, 5, 6] 

に相当します。 PEP 202によれば、 "フォーム[... for x... for y...]が入れ子になり、最後のインデックスは最も速く変化します。 "正しいもの"です。

ネストされたforループが書き込まれる順序であるため、この順序(外側から内側にネストされたforループに対応する)が選択されたようです。

しかし、リスト内包(上記の例ではa)の表現部分は、ネストされたループの中で最下位の式(上の例ではnew_list.append(a))に対応しているため、それが外側にfor a in bこととすべきである。すなわち、この表現に最も近いfor _ in _は、どちらの場合も同じでなければなりません:

>>> my_list = [[[[1, 2, 3], [4, 5, 6], ]]] 
>>> [a for a in b for b in c for c in d for d in my_list] 
NameError: name 'b' is not defined 

最速の変化ループはそう-発言、行動に最も近いように。これはまた、より論理的に段階的に左から右へ読むことに役立ちます。

これはユーザー間で共通の感想ですか?現在の構文実装が本当に「正しいもの」である理由について誰かが良い反論を持っていますか?

+6

これはBDFLの宣言です。 Guidoがここに投稿しない限り、すべての答えは推測と意見です、私は恐れています。 –

+6

私は、別の方法で行われた別の宇宙を想像しています。もう1人のユーザー、例えば、「hemaj」と呼ばれるユーザーがSOに来て、「なぜPythonのリストの理解ループが、 forループの順序? ".. – DSM

+3

私はこの質問が閉じられると期待していますが、"既存の 'for'ループの順序付けとの一貫性はGuidoが必要としていたすべての答えです。それはちょうどそれに逆らっていくために*キラー*良い理由を取っていたでしょう。 –

答えて

6

は考えてみましょう:

[leaf for branch in tree for leaf in branch] 

それは次のようにアンロール:我々はそれを他の方法

[leaf for leaf in branch for branch in tree] 

を書く場合

for branch in tree: 
    for leaf in branch: 
     yield leaf 

それはいくつかのレベルに平易な英語で、より意味をなすかもしれません、可能な反論は、ここでは "branch"という名前が(まだ)定義されていない状態で使われているということです。

+1

これは、 'for foo in bar'は常に' foo'を定義し、 'bar'は既に定義されていると考えている点で、良い点です。私の意見は変更されていません:/ – jameh

+2

しかし、私はあなたと同じ議論をすることができます - つまり、 'leaf'という名前は(まだ)定義されていないまま使われています。 (左から右へ読むと仮定して) – jameh

+0

述語計算のように、 'leaf'はここでは「自由変数」となります。例えば、how {x:P(x)}は「xそのようなP(x) " – wim

関連する問題