Why can I use the same name for iterator and sequence in a Python for loop?

This is more of a conceptual question. I recently saw a piece of code in Python (it worked in 2.7, and it might also have been run in 2.5 as well) in which a for loop used the same name for both the list that was being iterated over and the item in the list, which strikes me as both bad practice and something that should not work at all.

For example:

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

Yields:

    1
    2
    3
    4
    5
    5

Now, it makes sense to me that the last value printed would be the last value assigned to x from the loop, but I fail to understand why you'd be able to use the same variable name for both your parts of the for loop and have it function as intended. Are they in different scopes? What's going on under the hood that allows something like this to work?

What does dis tell us:

    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

The key bits are sections 2 and 3 - we load the value out of x (24 LOAD_NAME 0 (x)) and then we get its iterator (27 GET_ITER) and start iterating over it (28 FOR_ITER). Python never goes back to load the iterator again.

Aside: It wouldn't make any sense to do so, since it already has the iterator, and as Abhijit points out in his answer, Section 7.3 of Python's specification actually requires this behavior).

When the name x gets overwritten to point at each value inside of the list formerly known as x Python doesn't have any problems finding the iterator because it never needs to look at the name x again to finish the iteration protocol.

From: stackoverflow.com/q/24689967