Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does range() really create lists?

Tags:

python

range

Both my professor and this guy claim that range creates a list of values.

"Note: The range function simply returns a list containing the numbers from x to y-1. For example, range(5, 10) returns the list [5, 6, 7, 8, 9]."

I believe this is to be inaccurate because:

type(range(5, 10)) <class 'range'> 

Furthermore, the only apparent way to access the integers created by range is to iterate through them, which leads me to believe that labeling range as a lists is incorrect.

like image 720
chopper draw lion4 Avatar asked Apr 22 '14 13:04

chopper draw lion4


People also ask

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.

What does the range () function do?

The range() function returns a sequence of numbers, starting from 0 by default, and increments by 1 (by default), and stops before a specified number.

What is the difference between range and list?

range(0,3) returns a class of immutable iterable objects that lets you iterate over them, it does not produce lists, and they do not store all the elements in the range in memory, instead they produce the elements on the fly (as you are iterating over them) , whereas list(range(0,3)) produces a list (by iterating over ...


2 Answers

In Python 2.x, range returns a list, but in Python 3.x range returns an immutable sequence, of type range.

Python 2.x:

>>> type(range(10)) <type 'list'> >>> type(xrange(10)) <type 'xrange'> 

Python 3.x:

>>> type(range(10)) <class 'range'> 

In Python 2.x, if you want to get an iterable object, like in Python 3.x, you can use xrange function, which returns an immutable sequence of type xrange.

Advantage of xrange over range in Python 2.x:

The advantage of xrange() over range() is minimal (since xrange() still has to create the values when asked for them) except when a very large range is used on a memory-starved machine or when all of the range’s elements are never used (such as when the loop is usually terminated with break).

Note:

Furthermore, the only apparent way to access the integers created by range() is to iterate through them,

Nope. Since range objects in Python 3 are immutable sequences, they support indexing as well. Quoting from the range function documentation,

Ranges implement all of the common sequence operations except concatenation and repetition

...

Range objects implement the collections.abc.Sequence ABC, and provide features such as containment tests, element index lookup, slicing and support for negative indices.

For example,

>>> range(10, 20)[5] 15 >>> range(10, 20)[2:5] range(12, 15) >>> list(range(10, 20)[2:5]) [12, 13, 14] >>> list(range(10, 20, 2)) [10, 12, 14, 16, 18] >>> 18 in range(10, 20) True >>> 100 in range(10, 20) False 

All these are possible with that immutable range sequence.


Recently, I faced a problem and I think it would be appropriate to include here. Consider this Python 3.x code

from itertools import islice numbers = range(100) items = list(islice(numbers, 10)) while items:     items = list(islice(numbers, 10))     print(items) 

One would expect this code to print every ten numbers as a list, till 99. But, it would run infinitely. Can you reason why?

Solution

Because the range returns an immutable sequence, not an iterator object. So, whenever islice is done on a range object, it always starts from the beginning. Think of it as a drop-in replacement for an immutable list. Now the question comes, how will you fix it? Its simple, you just have to get an iterator out of it. Simply change

numbers = range(100)

to

numbers = iter(range(100))

Now, numbers is an iterator object and it remembers how long it has been iterated before. So, when the islice iterates it, it just starts from the place where it previously ended.

like image 160
thefourtheye Avatar answered Oct 17 '22 14:10

thefourtheye


It depends.

In python-2.x, range actually creates a list (which is also a sequence) whereas xrange creates an xrange object that can be used to iterate through the values.

On the other hand, in python-3.x, range creates an iterable (or more specifically, a sequence)

like image 38
sshashank124 Avatar answered Oct 17 '22 14:10

sshashank124