Home > Software engineering >  Loop counter behaving unexpectedly
Loop counter behaving unexpectedly

Time:12-19

I am having trouble understanding why the counter variable even though incremented within the nested loop, is not having any effect on the number of times the parent loop runs!

The code below gives the output 0 1 2 when the increment inside the nested loop is supposed to stop it from executing the second and the third time.

for i in range(3):
  print(i)
  for j in range(2):
    i = i   2

Is the i inside the nested for pointing to a different i!

CodePudding user response:

A for loop is a fancy kind of assignment statement; the loop index is assigned to at the start of each iteration.

The code

for i in range(3):
  print(i)
  for j in range(2):
    i = i   2

is effectively equivalent to

itr1 = iter(range(3))
while True:
    try:
        i = next(itr1)
    except StopIteration:
        break

    itr2 = iter(range(2))
    while True:
        try:
            j = next(itr2)
        except StopIteration:
            break

        i = i   2

The assignment i = next(itr1) ignores anything else done to i in the previous iteration: the value depends only on the state of itr1, not the current value of i.

CodePudding user response:

if you display i after the loop incrementing it, you'll see the change

for i in range(3):
    print(i)
    for _ in range(2):  # j is not used
        i  = 2
    print(i)  # I'm new!

each time the first line runs, it'll re-tag i with the next value from the range() sequence, discarding what it was before

CodePudding user response:

You don't store the result of the increment anywhere. It goes like this: i is assigned a value from range(), you print it, then j gets the assigned value, i = 1, and then you loop starts again, and i is assigned the next value from the range(). This should work though

for i in range(3):

  for j in range(2):
     
    i = i   2
    print(i)

CodePudding user response:

To achieve the effect you are looking for you would have to increment the iterator. You might think of it as incrementing the pointer, rather than the value at the pointer:

iterator = iter(range(123))

for i in iterator:
    print(i)
    next(iterator, None) #None here is a default, 
                         #and stops you getting an error if there is no 'next'.

      

Imagine a for loop in python is doing something like the following, which makes it very obvious why a value assigned to i within the body of the loop is lost. You are incrementing i when you really want to increment n

iterator = list(range(10))
n = 0
while n < len(iterator):
    n =1
    i = iterator[n]
    print(i)
    i = i 1
  • Related