4

First of all a disclaimer:

I don't want to use a code like this, I am aware it is a bad practice. As well I am not interested in tips on how to improve it, to make it right. What interests me is a theory.

How come code like this works in python 3.6:

ls = range(5)
for elem_a in ls:

    ls = range(5, 10)
    for elem_b in ls:
        print(elem_a, elem_b)

I am reassigning the value of ls while iterating through it. Is the value of ls in the first iteration stored in memory during the first execution of for elem_a in ls?

2
  • 3
    For the outer loop, ls is already range(5) beforehand and it just iterates through this iterable no matter it changes inside the loop. Commented Nov 2, 2018 at 9:35
  • Great, I thought so. Thank you, for the immediate answer. Commented Nov 2, 2018 at 9:42

1 Answer 1

7

Reassigning the variable you're looping over has no effect because the variable isn't re-evaluated for every iteration. In fact, the loop internally loops over an iterator, not over your range object.

Basically if you have a loop like this:

seq = range(5)
for elem in seq:
    seq = something_else

Python rewrites it to something like this:

seq = range(5)

loop_iter = iter(seq)  # obtain an iterator
while True:
    try:
        elem = next(loop_iter)  # get the next element from the iterator
    except StopIteration:
        break  # the iterator is exhausted, end the loop

    # execute the loop body
    seq = something_else

The crucial aspect of this is that the loop has its own reference to iter(seq) stored in loop_iter, so naturally reassigning seq has no effect on the loop.

All of this is explained in the compound statement documentation:

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 returned by the iterator.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the clear and in-depth explanation. Much appreciate it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.