Python's range() vs xrange() Functions

Both range() and xrange() are built-in functions in Python that are used to generate integers or whole numbers in a given range . The range() and xrange() comparison is relevant only if you are using both Python 2.x and Python 3 . It is because the range() function in python 3.x is just a re-implementation of the xrange() of python 2.x. It actually works the same way as the xrange does.
range() vs xrange() in Python

In Python 2.x:

  1. range() creates a list, so if you do range(1, 10000000) it creates a list in memory with 9999999 elements. This will become an expensive operation on very large ranges.

  2. xrange() is a sequence object that evaluates lazily. It is much more optimised, it will only compute the next value when needed (via an xrange sequence object) and does not create a list of all values like range() does.

In Python 3:

  1. range() does the equivalent of python's xrange(), and to get the list. If you need to actually generate the list, you will need to do:
list(range(1,10000000))

In python 3, range() does what xrange() used to do and xrange() does not exist. If you want to write code that will run on both Python 2 and Python 3, you can't use xrange().

Advantage:

  1. range()
The advantage of the range() type is that it is faster if iterating over the same sequence multiple times. On the other hand the xrange() has to reconstruct the integer object every time, but range() will have real integer objects . (It will always perform worse in terms of memory however). Also, xrange() isn't usable in all cases where a real list is needed. For instance, it doesn't support slices , or any list methods.
  1. xrange()
The advantage of the xrange() type is that an xrange() object will always take the same amount of memory, no matter the size of the range it represents. This is an opaque sequence type which yields the same values as the corresponding list, without actually storing them all simultaneously. For performance, especially when you're iterating over a large range, xrange() is usually better.

Syntax of range and xrange:

range(start, stop, step)
xrange(start, stop, step)

Return type:

  1. range() – This returns a list of numbers created using range() function.

  2. xrange() – This function returns the generator object that can be used to display numbers only by looping. Only particular range is displayed on demand and hence called lazy evaluation .

Deprecation of xrange()

In Python 3.x, the xrange() function does not exist anymore. The range() function now does what xrange() does in Python 2.x, so to keep your code portable, you might want to stick to using range() instead. Of course, you could always use the 2to3 tool that Python provides in order to convert your code, but that introduces more complexity.


When to Use Python's xrange and range

NameError: name 'xrange' is not defined

The error message 'xrange' is not defined would seem to indicate that you are trying to run a Python 2 codebase with Python 3 . In Python 2, an iterable object is often created with xrange() method , usually in a "for loop", which behaves very similarly to a generator. In Python 3, range() method is implemented the same as the xrange() method , so there is no dedicated xrange(). So, if you use xrange() in Python 3, it will generate NameError:name 'xrange' is not defined error.