1

The following code

lst = ['foo', 'bar', 'baz']
for lst in lst:
    print lst

gives me this output

foo
bar
baz

I would expect either an error or the following output:

['foo', 'bar', 'baz']
['foo', 'bar', 'baz']
['foo', 'bar', 'baz']

The code above is wrong and should have been

lst = ['foo', 'bar', 'baz']
for lst_element in lst:
    print lst_element

Why is it, that python although yields the expected output?

Frank Martin
  • 2,584
  • 2
  • 22
  • 25
  • What's wrong if it is already generating expected output? – ZdaR Jun 23 '15 at 13:08
  • 1
    Why did you expect an error? Python is strongly but dynamically typed, it has no problem with you shadowing `lst`. – jonrsharpe Jun 23 '15 at 13:10
  • @ZdaR: There is nothing wrong, but I'd like to understand what happens. And coming from other languages it is somehow a surprise to me that this code works and I would like to know why/how it works. – Frank Martin Jun 23 '15 at 13:20
  • @jonrsharpe: I would have expected that the iterable gets overwritten with the first loop. So I clearly have to read and learn about shadowing. – Frank Martin Jun 23 '15 at 13:23
  • @CoryKramer: You're right, my question addresses the same topic. But I was not able to find the question (not knowing that I need to search for iterator same name) - Sorry! – Frank Martin Jun 23 '15 at 13:46

1 Answers1

3

In Python, when you say

for identifier in iterable:

first an iterator will be created from the iterable. So, the actual object will not be used in the looping. Then the iterator will be iterated and the current value will be bound to the name identifier.

Quoting the official documentation of for,

for_stmt ::=  "for" target_list "in" expression_list ":" suite
          ["else" ":" suite]

The expression list is evaluated once; it should yield an iterable object. An iterator is created for the result of the expression_list. The suite is then executed once for each item provided by the iterator, in the order of ascending indices. Each item in turn is assigned to the target list using the standard rules for assignments, and then the suite is executed.

In your example, after the last iteration, lst will be referring to baz, not the list itself, because the for loop has bound the name lst to baz in the last iteration.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • the last sentence of your answer (after the last iteration, lst will be referring to baz) was the key for me to understand. thanks a lot. – Frank Martin Jun 23 '15 at 13:32