1. ホーム
  2. python

Pythonのforループでイテレータとシーケンスに同じ名前を使うことができるのはなぜですか?

2023-09-17 03:05:09

質問

これは、より概念的な質問です。私は最近、Python(それは2.7で動作し、同様に2.5でも実行されていたかもしれません)のコードの部分を見ました。 for ループが反復されるリストとリスト内のアイテムの両方に同じ名前を使用していたのですが、これは悪い習慣とまったく動作しないはずのものの両方として私を打ちます。

たとえば

x = [1,2,3,4,5]
for x in x:
    print x
print x

収量です。

1
2
3
4
5
5

さて、最後に出力される値が、ループから x に割り当てられた最後の値であることは理解できますが、なぜ同じ変数名を for ループの両方の部分に同じ変数名を使用して、意図したとおりに機能させることができるのか、理解できません。これらは異なるスコープにあるのでしょうか?このようなことが機能するようにするために、フードの下で何が起こっているのでしょうか?

どのように解決するのですか?

何をするのですか? dis は私たちに教えてくれます。

Python 3.4.1 (default, May 19 2014, 13:10:29)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from dis import dis
>>> dis("""x = [1,2,3,4,5]
... for x in x:
...     print(x)
... print(x)""")

  1           0 LOAD_CONST               0 (1)
              3 LOAD_CONST               1 (2)
              6 LOAD_CONST               2 (3)
              9 LOAD_CONST               3 (4)
             12 LOAD_CONST               4 (5)
             15 BUILD_LIST               5
             18 STORE_NAME               0 (x)

  2          21 SETUP_LOOP              24 (to 48)
             24 LOAD_NAME                0 (x)
             27 GET_ITER
        >>   28 FOR_ITER                16 (to 47)
             31 STORE_NAME               0 (x)

  3          34 LOAD_NAME                1 (print)
             37 LOAD_NAME                0 (x)
             40 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             43 POP_TOP
             44 JUMP_ABSOLUTE           28
        >>   47 POP_BLOCK

  4     >>   48 LOAD_NAME                1 (print)
             51 LOAD_NAME                0 (x)
             54 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             57 POP_TOP
             58 LOAD_CONST               5 (None)
             61 RETURN_VALUE

重要なのはセクション 2 と 3 です。 x ( 24 LOAD_NAME 0 (x) ) を取得し、そのイテレータ ( 27 GET_ITER ) を取得し、それに対する反復処理を開始します ( 28 FOR_ITER ). Python はイテレータを再び読み込むために戻ることはありません。 .

脇です。 すでにイテレータを持っているので、そうしても意味はないでしょうし、また、このように Abhijitが彼の回答で指摘しているように , Pythonの仕様の7.3節にある は実際にこの動作を要求しています)。

という名前の場合 x という名前のリストが上書きされ、その中のそれぞれの値を指すようになります。 x Python はイテレータを見つけるのに何の問題もありません。 x という名前をもう一度見る必要がないからです。