Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If range() is a generator in Python 3.3, why can I not call next() on a range?

Perhaps I've fallen victim to misinformation on the web, but I think it's more likely just that I've misunderstood something. Based on what I've learned so far, range() is a generator, and generators can be used as iterators. However, this code:

myrange = range(10) print(next(myrange)) 

gives me this error:

TypeError: 'range' object is not an iterator 

What am I missing here? I was expecting this to print 0, and to advance to the next value in myrange. I'm new to Python, so please accept my apologies for the rather basic question, but I couldn't find a good explanation anywhere else.

like image 439
Jeff Avatar asked Oct 26 '12 18:10

Jeff


People also ask

Can we call generator multiple times in Python?

Unless your generator is infinite, you can iterate through it one time only. Once all values have been evaluated, iteration will stop and the for loop will exit. If you used next() , then instead you'll get an explicit StopIteration exception.

How does range () function of Python generate a list?

To convert a Python Range to Python List, use list() constructor, with range object passed as argument. list() constructor returns a list generated using the range. Or you can use a for loop to append each item of range to list.

Is Range () An iterable?

Python | range() does not return an iterator In python range objects are not iterators. range is a class of a list of immutable objects. The iteration behavior of range is similar to iteration behavior of list in list and range we can not directly call next function.

Does range return an iterable?

range returns an iterable, not an iterator. It can make iterators when iteration is necessary.


1 Answers

range is a class of immutable iterable objects. Their iteration behavior can be compared to lists: you can't call next directly on them; you have to get an iterator by using iter.

So no, range is not a generator.

You may be thinking, "why didn't they make it directly iterable"? Well, ranges have some useful properties that wouldn't be possible that way:

  • They are immutable, so they can be used as dictionary keys.
  • They have the start, stop and step attributes (since Python 3.3), count and index methods and they support in, len and __getitem__ operations.
  • You can iterate over the same range multiple times.

>>> myrange = range(1, 21, 2) >>> myrange.start 1 >>> myrange.step 2 >>> myrange.index(17) 8 >>> myrange.index(18) Traceback (most recent call last):   File "<stdin>", line 1, in <module> ValueError: 18 is not in range >>> it = iter(myrange) >>> it <range_iterator object at 0x7f504a9be960> >>> next(it) 1 >>> next(it) 3 >>> next(it) 5 
like image 191
Oleh Prypin Avatar answered Sep 25 '22 01:09

Oleh Prypin