xrange and range in Python
The flippant answer is that range exists and xrange doesn’t 
In Python 2, range returned a list and xrange returned an iterable that did not actually generate the full list when called. So range(2**23458) would run you out of memory, but xrange(2**23458) would return just fine and be useful.
Python 3 did away with range and renamed xrange to range, so it’s always safe to call range with as large a value as you like.
Hi Zachary,
xrange was not an iterator. It, like the Python 3 range (which as
you say is the old xrange renamed) is a lazy sequence which computes
its values on demand, rather than pre-allocating a list.
The test for an iterator is to call iter and see if it returns the
identical value:
>>> r = range(100000)
>>> it = iter(r)
>>> iter(it) is it # is "it" an iterator? yes
True
>>> iter(r) is r # is "r" (range object) an iterator? no
False
We can compare their types:
>>> print type(r), type(it)
<type 'xrange'> <type 'rangeiterator'>
and confirm that range objects provide the full Sequence interface:
>>> import collections
>>> isinstance(r, collections.Sequence)
True
All of this remains the case in Python 3: range is not an iterator, it
is a lazy sequence.
I am also looking difference between xrange and range in python
Zachary’s post has a good explanation for the difference:
aside from a minor error in describing xrange as an iterator, but
otherwise his explanation is excellent.
Yes, sorry; I used the wrong syllable in haste. I’ve edited my original post to avoid future confusion.