2017-10-08 16 views
1

Iは、次のコードを持っている。後者は生成しながら、奇妙な挙動

[sl for sl in [1,[2,3],4,5]] 

さらに:iが(出力換算)等価であると考え

[e for e in [sl] for sl in [1,[2,3],4,5]] 

[1,[2,3],4,5]旧リターン: [5, 5, 5, 5]


は、私はそれが必要だと思います入れ子になったfor-statementsの評価方法と何か関係があります。

ここでも同様のケースが見つかったが、匿名関数が使用されているため、この動作の原因は異なるはずです。

明らかに、私には何かがありません。私は見ません。

はパトリックが指摘したように、2 forの順序が間違っているとslが前に定義されていない限り、実行すべきではありません任意の明確化

UPDATE

いただきありがとうございます。私は通訳の例を実行し、[sl for sl in [1,[2,3],4,5]]globals()


で、リストの最後の値にslセットを残して最初に実行された今では、これが評価されるかを理解するために素晴らしいことだので、私はここで自分自身をだまさ

出力が [5, 5, 5, 5]であるためには、
[e for e in [sl] for sl in [1,[2,3],4,5]] 

があります。

答えて

2

slはコードのどこかに定義されていますか?おそらく5として?書かれているように、あなたの最初の例は実行されるべきではなく、Python 3.6では私のために実行されません。それを書くための正しい方法は、それが使用される前に、ここでslが定義されている

[e for sl in [1,[2,3],4,5] for e in [sl]] 

注だろう。

編集:

Pythonは左から右のリスト内包表記を読み取ります。 for e in [sl]になると、残りの行を読み取ることなく、すでに知っている式に基づいて式[sl]が評価されます。あなたは、結果リストに5 4回を取得し、[[1,[2,3],4,5]]で4 slがあると理解が、その後

[e for e in [5] for sl in [1,[2,3],4,5]] 

のようなものであるリスト。

リストの内包表記を書いたとき、それが最大に小さいから

e for e in x for x in y for y in z #wrong 

をそれらを書くのが自然だが、通訳は、あなたがネストされた内包表記で使う識別子を認識するように、あなたは実際に、右から左に書き込む必要があります

for e in x: 
    for x in y: 
     for y in z: 
      print(e) 

e for y in z for x in y for e in x 

これは、通常のforループと違いはありません

は明らかに間違っていますし、リスト内包も同じです。

+0

まあいや、それは実際にはそのラインだと私は例を実行しています通訳の中で。しかし、はい、あなたは本当に正しいです!以前は[1、[2,3]、4,5]でslを実行していたはずなので、 'sl'は' globals() 'のリストの最後の値に設定されたままです。それは逆の 'のためになぜ働いたのかも説明します。しかし、 'sl'をグローバル変数で' 5'に設定すると、[1、[2,3]、4,5]]のslの[e for e]の挙動をどのように説明できますか? –

+0

私は、ローカルの 'for'の左端がグローバル変数を正しく上書きすることを理解しています。私はちょうど 'sl'が既に設定されているときに私のソリューションがどのように評価されるのか理解したいと思っています –

+0

@holak私の編集をご覧ください(コメントに収まるように大きくなっています)。それでも助けなければ、もっとお気軽にお尋ねください。 –

0

コードが実行できる唯一の方法は、slが他の場所で定義されている場合です。それは(5として)である場合、コード:

[5,5,5,5] 

理由:

sl = 5 

[e for e in [sl] for sl in [1,[2,3],4,5]] 

はの出力を生成しますか?これが起こっている

その理由はrightからleftからfor-loopsevaluate。だから、最初はそれが起こるでe5に割り当てられている - ちょうどあなたが可能性として:

[i for i in [9]] 

9を与えることになります。

だから今、私たちは関係なく、右端のfor-loopの、eの値は常にslのそれは我々の場合5にそうなることを知っています。さて、なぜ出力は[5,5,5,5]ですか?変数slが再利用されているので、混乱します。ただし、leftrightと評価されたため、list-comprehensionleftには影響しません。したがって、eは、slが右側にある場合でも、常に[sl]5)の値を持ちます。右手loopは単にカウンタとして機能します。 4の要素があるので(1[2,3]45)、左手部分は4回実行されます。しかし、eは常に5なので、それぞれeと呼ばれ、5となり、結果は[5,5,5,5]となります。

右手側は単純にカウンタであることを実証するために、次はすべて[5,5,5,5]のと同じ結果になります:

[e for e in [sl] for _ in [1, [2,3], 4, 5]] 
[e for e in [sl] for sl in [0, 0, 0, 0]] 
[e for e in [sl] for _ in range(4)] 
[e for e in [sl] for sl in range(4)]