0
people = ['mago','pipa','john','mat']
>>> for people in people:
    print(people)


mago
pipa
john
mat
>>> for people in people:
    print(people)


m
a
t
>>> for people in people:
    print(people)


t
>>> for people in people:
    print(people)


t
>>> for people in people:
    print(people)


t
>>> for people in people:
    print(people)
Xantium
  • 11,201
  • 10
  • 62
  • 89
Tukson
  • 17

1 Answers1

5

A for loop does not create a new scope for the index; you are overwriting the list people with the loop index people.

A for loop is almost syntactic sugar for the following code:

# for people in people:   # iter() is called implicitly on the iterable
#    print(people)
people_itr = iter(people)
while True:
    try:
        people = next(people_itr)
    except StopIteration:
        break
    print(people)
del people_itr

So although you have a reference to the list originally referenced by people, the name people is constantly updated to reference one element of that list. When you run your second loop, people is now a reference to the last string in the list. The third and subsequent loops represent a fixed point; an iterator over a string returns successive 1-character strings, so you quickly reach a point where the string is its own only element.

With your example, people is bound to "mat", not your list, after the first loop. After the second (and third, and fourth) loop, people is bound to "t".

You can see the same thing by chaining calls to __getitem__ (i.e., [-1]):

>>> people[-1]
'mat'
>>> people[-1][-1]
't'
>>> people[-1][-1][-1]
't'
>>> people[-1][-1][-1][-1]
't'
chepner
  • 497,756
  • 71
  • 530
  • 681
  • 1
    If it did, you would then need some way to refer to variables from the enclosing scope in the event you shadowed a name. – chepner May 18 '18 at 17:35
  • If only we had a keyword like `nonlocal` ;-) – Adam Smith May 18 '18 at 17:42
  • `nonlocal` wouldn't help here, unless you significantly changed its semantics. `nonlocal p` means that `p` here is the same object that `p` in the enclosing scope refers to; it doesn't let you access a shadowed name. – chepner May 18 '18 at 17:48
  • Oh I think I misunderstood you then -- why would you need to refer to a shadowed variable from an enclosing scope? You can't do that currently (since shadowing a variable simply redefines it) – Adam Smith May 18 '18 at 17:53
  • If a new scope did not allow access to shadowed names, then you may as well make sure to use unique names, but then there's no real need for a new scope. You seem to be saying that the loop index should simply not exist after the loop exits, but then you can't use a loop to search a container by exiting once the index is equal to the desired value. – chepner May 18 '18 at 18:00