In Python 3.x ,
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 all the elements and appending to the list internally) .
Example -
>>> range(0,3)
range(0, 3)
>>> list(range(0,3))
[0, 1, 2]
Ideally, if you only want to iterate over that range of values , range(0,3) would be faster than (list(range(0,3)) because the latter has the overhead of producing a list before you start iterating over it.
In Python 2.x , range(0,3) produces an list, instead we also had an xrange() function that has similar behavior of range() function from Python 3.x (xrange was renamed to range in Python 3.x)
For Python 3.5, From the documentation -
Range objects implement the collections.abc.Sequence ABC, and provide features such as containment tests, element index lookup, slicing and support for negative indices
So you can do things like -
>>> range(0,10)[5]
5
>>> range(0,10)[3:7]
range(3, 7)
>>> 5 in range(6,10)
False
>>> 7 in range(1,8)
True
And all of these are constant time operations , as can be seen from this test -
In [11]: %timeit a = xrange(0,1000000)[1000]
1000000 loops, best of 3: 342 ns per loop
In [12]: %timeit a = xrange(0,1000000)[10000]
1000000 loops, best of 3: 342 ns per loop
In [13]: %timeit a = xrange(0,1000000)[100000]
1000000 loops, best of 3: 342 ns per loop
In [14]: %timeit a = xrange(0,1000000)[999999]
1000000 loops, best of 3: 342 ns per loop
In [15]: %timeit a = xrange(0,10000000)[9999999]
1000000 loops, best of 3: 339 ns per loop
In [16]: %timeit a = xrange(0,1000000000000)[9999999999]
1000000 loops, best of 3: 341 ns per loop
Answer from Anand S Kumar on Stack OverflowDoes range() return a list or a range object?
python - Does range() really create lists? - Stack Overflow
What's the difference between for i in list: vs for i in range(len(list)):
python 3.x - Difference between [range(5)] and list(range(5)) - Stack Overflow
In Python 3.x ,
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 all the elements and appending to the list internally) .
Example -
>>> range(0,3)
range(0, 3)
>>> list(range(0,3))
[0, 1, 2]
Ideally, if you only want to iterate over that range of values , range(0,3) would be faster than (list(range(0,3)) because the latter has the overhead of producing a list before you start iterating over it.
In Python 2.x , range(0,3) produces an list, instead we also had an xrange() function that has similar behavior of range() function from Python 3.x (xrange was renamed to range in Python 3.x)
For Python 3.5, From the documentation -
Range objects implement the collections.abc.Sequence ABC, and provide features such as containment tests, element index lookup, slicing and support for negative indices
So you can do things like -
>>> range(0,10)[5]
5
>>> range(0,10)[3:7]
range(3, 7)
>>> 5 in range(6,10)
False
>>> 7 in range(1,8)
True
And all of these are constant time operations , as can be seen from this test -
In [11]: %timeit a = xrange(0,1000000)[1000]
1000000 loops, best of 3: 342 ns per loop
In [12]: %timeit a = xrange(0,1000000)[10000]
1000000 loops, best of 3: 342 ns per loop
In [13]: %timeit a = xrange(0,1000000)[100000]
1000000 loops, best of 3: 342 ns per loop
In [14]: %timeit a = xrange(0,1000000)[999999]
1000000 loops, best of 3: 342 ns per loop
In [15]: %timeit a = xrange(0,10000000)[9999999]
1000000 loops, best of 3: 339 ns per loop
In [16]: %timeit a = xrange(0,1000000000000)[9999999999]
1000000 loops, best of 3: 341 ns per loop
It depends on what version of Python you are using.
In Python 2.x, range() returns a list, so they are equivalent.
In Python 3.x, range() returns an immutable sequence type, you need list(range(0,2)) to get a list.
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()overrange()is minimal (sincexrange()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.SequenceABC, 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
rangereturns an immutable sequence, not an iterator object. So, wheneverisliceis done on arangeobject, 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,numbersis an iterator object and it remembers how long it has been iterated before. So, when theisliceiterates it, it just starts from the place where it previously ended.
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)
Sorry this may seem like a super python noob question, but I just started learning and I am stuck on this idea. Why is it that sometimes one makes the code work but not the other? What's the difference between them and can someone explain it in a way that a beginner can understand?