0

Is it possible to modify your iterator in for loops?

My code isn't running as expected (printing 0-9). I can do it with a while loop but looking for a for loop solution.

for r in range(0,10):
    if(r==0):
        print (0)
        print (1)
        print (2)
        r = r+3
    else:
        print(r)
3
  • why would you not expect 0 - 13? Commented Apr 20, 2015 at 19:44
  • what do you actually expect as output? Commented Apr 20, 2015 at 19:47
  • 0-9, but printing 0-9 is not the issue, modifying the iterator is. Commented Apr 20, 2015 at 19:56

4 Answers 4

4

Doing:

r = r+3

will not work as expected because r is assigned to the value just returned by the iterator, not the iterator itself. To advance the iterator, you need to call next on it.

You can do this by first saving the iterator in a variable and looping over that:

it = iter(range(0,10))
for r in it:

This will allow you to then call next on it inside the loop:

it = iter(range(0,10))
for r in it:
    if(r==0):
        print (0)
        print (1)
        print (2)
        for _ in range(3): # Advance the iterator by 3.
            next(it)
    else:
        print(r)

Note however that, as @StevenRumbalski said, calling next on an empty iterator will raise a StopIteration exception. Sometimes this behavior is desirable, but if not, you can specify a default value to return:

next(it, None)

This will effectively make the line a no-op.

1
  • thanks a lot. but for _ in range(2) is working properly. Commented Apr 20, 2015 at 19:58
3

Assigning to the loop variable will simply be overwritten by the next iteration of the loop. The loop variable is an assignment like anything else. This PyCon 2015 talk might help explain the details: Python Names and Values.

1
  • you figured out what the question was before I did :P (+1) Commented Apr 20, 2015 at 19:47
3
for r in range(10):
    print r

I guess... assuming i understood ...

[edit] Oh i finally figured out what you meant ... the answer is not really r is reasigned each loop

you could however affect the iterator

my_iter = xrange(10)
for value in my_iter:
   if value == 0:
      print "A",value
      print "B",next(my_iter)
      print "C",next(my_iter)
   else:
      print value
1
  • no, sorry but you didn't. This is a simple example, the thing is not to print numbers from 0 to 10, it is modifying your iterator. Commented Apr 20, 2015 at 19:47
0

for r in range(0, 10) assigns to r each iteration. This means that assignments to the loop variable will not persist to the next iteration.

Your for-loop is equivalent to:

it = iter(range(0, 10))
while True:
    try:
        r = next(it)
    except StopIteration:
        break
    if(r==0):
        print (0)
        print (1)
        print (2)
        r = r+3
    else:
        print(r)

That r = next(it) clobbers any assignment you made to the name r in previous iterations. The same thing happens implicitly in your for-loop.

If your end goal is to advance your iterator by a certain number of steps, call next(it) the number of times you wish to advance it (as per iCodez's answer).

Not the answer you're looking for? Browse other questions tagged or ask your own question.