range creates a list, so if you do range(1, 10000000) it creates a list in memory with 9999999 elements.range returns a static list at runtime.

xrange is a sequence object that evaluates lazily.

xrange is not exactly a generator but it evaluates lazily and acts like a generator. xrange(x).__iter__() is a generator.

xrange only stores the range parameters and generates the numbers on demand.

xrange returns an iterator and only keeps one number in memory at a time. range keeps the entire list of numbers in memory.

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. There are no consistent performance advantages.

Use xrange if you want to generate a list for a gigantic range, say 1 billion, especially when you have a "memory sensitive system" like a cell phone.

Use range if you want to iterate over the list several times.

PS: Python 3.x's range function == Python 2.x's xrange function.

import time

for x in range(1, 10):

t = time.time()

[v*10 for v in range(1, 10000)]

print "range: %.4f" % ((time.time()-t)*100)

t = time.time()

[v*10 for v in xrange(1, 10000)]

print "xrange: %.4f" % ((time.time()-t)*100)

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

>>> type(range(10))

<type 'list'>

>>> type(xrange(10))

<type 'xrange'>

>>> type(range(10))

<class 'range'>

xrange is a sequence object that evaluates lazily.

xrange is not exactly a generator but it evaluates lazily and acts like a generator. xrange(x).__iter__() is a generator.

xrange only stores the range parameters and generates the numbers on demand.

xrange returns an iterator and only keeps one number in memory at a time. range keeps the entire list of numbers in memory.

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. There are no consistent performance advantages.

**When to use which?**Use xrange if you want to generate a list for a gigantic range, say 1 billion, especially when you have a "memory sensitive system" like a cell phone.

Use range if you want to iterate over the list several times.

PS: Python 3.x's range function == Python 2.x's xrange function.

**Example:**import time

for x in range(1, 10):

t = time.time()

[v*10 for v in range(1, 10000)]

print "range: %.4f" % ((time.time()-t)*100)

t = time.time()

[v*10 for v in xrange(1, 10000)]

print "xrange: %.4f" % ((time.time()-t)*100)

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'>