xrange

Raymond Hettinger vze4rx4y at verizon.net
Sun Jun 22 19:44:41 EDT 2003


"Bryan" <belred1 at yahoo.com>
> in 2.3, what is the best way to write this:
>
> for i in xrange(100): print 'Hello'
>
> i used timeit and it seems that repeat is about 10% faster.
>
> timeit -s"from itertools import repeat" "for i in repeat(None, 100): pass"
> 100000 loops, best of 3: 10.4 usec per loop
>
> timeit "for i in xrange(100): pass"
> 100000 loops, best of 3: 11.6 usec per loop
>
> will xrange be obsoleted?  what is the best idiom for repeating a loop n
> times in 2.3 now where you don't care about the index value?


What is "best" is a value judgement and varies with the circumstances.
When using Python, following Guido's examples and advice usually
leads to good results.

In general, range(n) is a simple consistent way to go.  GvR uses this
is most of his code.

When n gets large enough and/or space becomes enough of an issue
xrange(n) is generally the next best choice.  The python library is
full of cases where xrange is used in an inner loop.  Personally, I use
xrange for almost everything.

itertools.repeat(obj, n) was not intended to be "second or third way to
do it".  It was included in the module to meet a very specific need for
supplying repeated arguments to imap() and ifilter():

   cubeiter = imap(operator.pow, count(), repeat(3))

That being said, it does do slightly less work than xrange() because it
doesn't have to create a new object on every iteration.  So, it can be
used instead of xrange(n) or [None]*n in situtations where:

  1.  An interation index is not needed
  2.  Speed and space are so important that a you can tolerate a less than
       beautiful construct like:  for _ in itertools.repeat(None, n)

Such a case arises in the code for timeit.py.  The beauty and simplicity
of range(n) or xrange(n) is secondary in importance to a key operational
goal for the timer to produce high quality timings which depend on
low timer overhead and minimal impact on memory consumption.
Accordingly, GvR used itertools.repeat(n) in that one situation.  AFAICT,
he has never used it elsewhere.  That should provide good guidance for
you to do the same

For Py3.0, xrange() will likely go away.  Right now, it meets an important
need for an iteration counter that doesn't eat memory for breakfast.  For
Py3.0, range() will probably return a fast, memory efficient iterator.


Raymond Hettinger






More information about the Python-list mailing list