2016-11-22 2 views
1

私はこのコードブロックを実行しましたが、出力は驚くべきものでした。私は私が私を再利用していることを知っている、私の質問はなぜ私は再割り当てされて以来、最初の反復後にループが終了しない!Pythonブロックスコープ - 誰かがこれを説明します

コード:

for i in range(3): 
    print '=====' 
    print 'Outer I: ', i 
    print '=====' 
    for j in range(2): 
     print 'J', j 
     for i in range(5): 
      print 'Inner I', i 
    print '=====' 
    print 'Outer I Again: ', i 
    print '=====' 

出力:

===== 
Outer I: 0 
===== 
J 0 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
J 1 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
===== 
Outer I Again: 4 
===== 
===== 
Outer I: 1 
===== 
J 0 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
J 1 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
===== 
Outer I Again: 4 
===== 
===== 
Outer I: 2 
===== 
J 0 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
J 1 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
===== 
Outer I Again: 4 

ここでは混乱しているものです:

  • 私はループが最初の反復の後に壊れることを期待するが、それ ではない。
  • 同じ理由で、最初の印刷ステートメント "外部I" がiの正しい値を出力します。
  • 2番目の外側の印刷ステートメント "外側に戻る"は、間違った値を印刷します。

私はこれをPython 2.7 with CPythonで実行しています。

+0

あなたのコードは間違っています。内部ループに 'i'変数を再利用しています:' iの範囲(5): ' – EdChum

+0

はおそらくあなたが望むものを見つけるでしょう。 ** inner i **を別の変数** k **に置き換えます。それは魔法のように動作することがわかります!! ;) –

+1

Pythonにブロックスコープはありません。 [Scoping Rulesの簡単な説明](http://stackoverflow.com/questions/291978/short-description-of-scoping-rules)と[Pythonのブロックスコープ](http://stackoverflow.com/questions/6167923)を参照してください。/block-scope-in​​-python) –

答えて

3

このコードには、内部にiまたは外部iはありません。2つの異なるループに割り当てられた単一のi変数があります。 最初の反復後にループが中断するのはなぜですか? Pythonのforは、基本的には他の言語のfor eachループです。与えられたイテレータまたはジェネレータのメンバを反復処理します。 range関数は要素のリスト[0,1,2,3,4]を返し、各反復iにリストの次の値が与えられ、現在の値iは外側ループとは関係ありません。

これは、最初のOuter Iが期待する値のiを出力しますが、2番目の値(内部ループ後)は表示されないのはこのためです。

0

あなたはあなたの内側のループでi変数を再利用している:

for i in range(5) 

ので、あなたは以下を参照してください

Outer I Again: 4 

あなたが別の変数名に変更した場合に予想されるように、それは動作します:

In [12]: 
for i in range(3): 
    print('=====') 
    print('Outer I: ', i) 
    print('=====') 
    for j in range(2): 
     print('J', j) 
     for l in range(5): 
      print('Inner I', l) 
    print('=====') 
    print('Outer I Again: ', i) 
    print('=====') 

===== 
Outer I: 0 
===== 
J 0 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
J 1 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
===== 
Outer I Again: 0 
===== 
===== 
Outer I: 1 
===== 
J 0 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
J 1 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
===== 
Outer I Again: 1 
===== 
===== 
Outer I: 2 
===== 
J 0 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
J 1 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
===== 
Outer I Again: 2 
===== 
0

変数を再利用していますが、ターゲット変数は同じままです。この場合、変数のスコープは内部のiとは変わりません。文字列や整数のような不変のオブジェクトを扱う場合は、この問題に直面しません。もう1つの変数の代わりに他の変数を使用すれば、良い結果が得られます。

+0

Mutabilityはそれとは関係ありません。*例は実際には整数を扱っていますが、あなたが指摘しているのは不変です。 –

関連する問題