Reputation: 305
According to the Python documentation, when I do range(0, 10) the output of this function is a list from 0 to 9 i.e. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]. However the Python installation on my PC is not outputting this, despite many examples of this working online.
Here is my test code...
test_range_function = range(0, 10)
print(test_range_function)
print(type(test_range_function))
The output of this I'm thinking should be the list printed, and the type function should output it as a list. Instead I'm getting the following output...
c:\Programming>python range.py
range(0, 10)
<class 'range'>
I haven't seen this in any of the examples online and would really appreciate some light being shed on this.
Upvotes: 9
Views: 12845
Reputation: 49182
range() does not return an iterator, it is not iterator it is iterable. iterators protocol has 2 methods. __iter__
and __next__
r=range(10)
'__ iter __' in dir(r) # True
`__ next __` in dir(r) # False
iterable protocol requires __iter__
which returns an iterator.
r.__iter__()
# <range_iterator object at 0x7fae5865e030>
range() uses lazy eveluation. That means it does not precalculate and store range(10)
. its iterator, range_iterator, computes and returns elements one at a time. This is why when we print a range object we do not actually see the contents of the range because they don't exist yet!.
Upvotes: 1
Reputation: 250881
That's because range
and other functional-style methods, such as map
, reduce
, and filter
, return iterators in Python 3. In Python 2 they returned lists.
range()
now behaves likexrange()
used to behave, except it works with values of arbitrary size. The latter no longer exists.
To convert an iterator to a list you can use the list
function:
>>> list(range(5)) #you can use list()
[0, 1, 2, 3, 4]
Upvotes: 19
Reputation: 318478
Usually you do not need to materialize a range into an actual list but just want to iterate over it. So especially for larger ranges using an iterator saves memory.
For this reason range()
in Python 3 returns an iterator instead (as xrange()
did in Python 2). Use list(range(..))
if you want an actual list instead for some reason.
Upvotes: 6