-3

For the following code:

x = range(10)
for i in x:
    print(i)
    for j in x:
        print(">> %d" % j)
        break

I would have expected the output to be:

0 
>> 1
2
>> 3
..

but instead, it is:

0
>> 0
1
>> 0
2
>> 0
..

Why does range behave in this way?

lumisota
  • 101
  • 4

2 Answers2

3

By converting x to an iterator, you can achieve your expected behavior.

x = iter(range(10))

for i in x:
    print(i)
    for j in x:
        print('> {}'.format(j))
        break

which returns

0
> 1
2
> 3
4
> 5
6
> 7
8
> 9

What this shows us is that the problem does not lie with the breaking out of the inner loop per say but rather with range not being depleted as you loop over it. This happens because range is not an iterator and thus it restarts every time instead of picking up from where it left off.

Ma0
  • 15,057
  • 4
  • 35
  • 65
  • So, given that `range` is iterable, but not an iterator, does that mean that each `for` loop creates an iterator from it implicitly? – lumisota Feb 07 '18 at 10:42
  • An iterator is **not** implicitly created; you cannot call `next()` on a `range()` object. It is simply an iterable. – Ma0 Feb 07 '18 at 10:43
  • @lumisota Take a look at this [in depth answer](https://stackoverflow.com/a/28353158/6162307). It is a nice read. – Ma0 Feb 07 '18 at 10:49
2
for j in x:
        print(">> %d" % j)
        break

You are breaking the loop of J causing the value of J to reset and go back to 0 everytime.

Farhan Qasim
  • 990
  • 5
  • 18