FiveAlive
FiveAlive

Reputation: 305

Why Is the Output of My Range Function Not a List?

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

Answers (3)

Yilmaz
Yilmaz

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

Ashwini Chaudhary
Ashwini Chaudhary

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.

What’s New In Python 3.0:

range() now behaves like xrange() 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

ThiefMaster
ThiefMaster

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

Related Questions