In Python 2, range
function returns a list while xrange
creates a special xrange
object, which is an immutable sequence, which unlike other built-in sequence types, doesn't support slicing and has neither index
nor count
methods:
print(range(1, 10))
# Out: [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(isinstance(range(1, 10), list))
# Out: True
print(xrange(1, 10))
# Out: xrange(1, 10)
print(isinstance(xrange(1, 10), xrange))
# Out: True
In Python 3, xrange
was expanded to the range
sequence, which thus now creates a range
object. There is no xrange
type:
print(range(1, 10))
# Out: range(1, 10)
print(isinstance(range(1, 10), range))
# Out: True
# print(xrange(1, 10))
# The output will be:
#Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
#NameError: name 'xrange' is not defined
Additionally, since Python 3.2, range
also supports slicing, index
and count
:
print(range(1, 10)[3:7])
# Out: range(3, 7)
print(range(1, 10).count(5))
# Out: 1
print(range(1, 10).index(7))
# Out: 6
The advantage of using a special sequence type instead of a list is that the interpreter does not have to allocate memory for a list and populate it:
# range(10000000000000000)
# The output would be:
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# MemoryError
print(xrange(100000000000000000))
# Out: xrange(100000000000000000)
Since the latter behaviour is generally desired, the former was removed in Python 3.
If you still want to have a list in Python 3, you can simply use the list()
constructor on a range
object:
print(list(range(1, 10)))
# Out: [1, 2, 3, 4, 5, 6, 7, 8, 9]
In order to maintain compatibility between both Python 2.x and Python 3.x versions, you can use the builtins
module from the external package future
to achieve both forward-compatiblity and backward-compatiblity:
#forward-compatible
from builtins import range
for i in range(10**8):
pass
#backward-compatible
from past.builtins import xrange
for i in xrange(10**8):
pass
The range
in future
library supports slicing, index
and count
in all Python versions, just like the built-in method on Python 3.2+.