classification
Title: Code in xrange documentation does not work
Type: behavior Stage: needs patch
Components: Documentation Versions: Python 2.6
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: georg.brandl Nosy List: flox, georg.brandl, mm, rhettinger
Priority: normal Keywords:

Created on 2010-01-16 21:55 by mm, last changed 2010-04-05 11:48 by georg.brandl. This issue is now closed.

Files
File name Uploaded Description Edit
irange.py mm, 2010-01-16 23:07 irange code
Messages (10)
msg97912 - (view) Author: Martin Manns (mm) Date: 2010-01-16 21:55
In the Python 2.6.4 documentation "2. Built-in Functions" at
http://docs.python.org/library/functions.html,
the section about the xrange function (paragraph "CPython implementation detail") contains the following code:

islice(count(start, step), (stop-start+step-1)//step)

However, count only accepts one parameter, so that this solution does
not work. Furthermore, islice only accepts positive values for step.

Therefore, the code does not work.

I tested this with Python 2.5.4 and Python 2.6.4 on Debian Linux (AMD64).
msg97917 - (view) Author: Florent Xicluna (flox) * (Python committer) Date: 2010-01-16 22:56
Confirmed. The snippet works for 3.1 and 2.7a2.

from itertools import count, islice
irange = lambda start, stop, step: islice(count(start, step), (stop-start+step-1)//step)


The documentation needs update for 2.6 only.

This kind of snippet seems backward compatible for 2.6:
irange = lambda start, stop, step: islice(count(start), 0, stop, step)
msg97918 - (view) Author: Martin Manns (mm) Date: 2010-01-16 23:07
The new snippet does not work for me:

>>> list(irange(-12, 20, 4))
[-12, -8, -4, 0, 4]

I have attached code that seems to work.
It is more than a snipped though.
msg97921 - (view) Author: Florent Xicluna (flox) * (Python committer) Date: 2010-01-16 23:37
Right. Insufficient test.

This snippet looks better, if we provide a replacement for 2.6.

>>> irange = lambda start, stop, step: islice(count(start), 0, stop-start, step)
msg97922 - (view) Author: Martin Manns (mm) Date: 2010-01-16 23:50
The new snippet works better.

>>> list(irange(-12, 20, 4))
[-12, -8, -4, 0, 4, 8, 12, 16]

However, it does not like large or negative slices:

>>> list(irange(-2**65,2**65,2**61))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
OverflowError: long int too large to convert to int

>>> list(irange(32,2,-3))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
ValueError: Indices for islice() must be non-negative integers or None.

Perhaps the documentation can mention that.
msg97927 - (view) Author: Florent Xicluna (flox) * (Python committer) Date: 2010-01-17 00:33
You will prefer this one. It is as fast as the 2.7 version.
The restrictions are described in the itertools documentation.


from itertools import count, takewhile
irange = lambda start, stop, step: takewhile(lambda x: x<stop, (start+i*step for i in count()))

>>> list(irange(-2**65,2**65,2**61))
[-36893488147419103232L, ...
msg97928 - (view) Author: Florent Xicluna (flox) * (Python committer) Date: 2010-01-17 01:09
If you need also negative steps:

from itertools import count, takewhile
def irange(start, stop, step):
    if step < 0:
        cond = lambda x: x > stop
    else:
        cond = lambda x: x < stop
    return takewhile(cond, (start + i * step for i in count()))
msg97929 - (view) Author: Martin Manns (mm) Date: 2010-01-17 01:19
Great solution!

Thank you
msg99624 - (view) Author: Martin Manns (mm) Date: 2010-02-20 17:55
So could we replace

"If a larger range is needed, an alternate version can be crafted using the itertools module: islice(count(start, step), (stop-start+step-1)//step)."

by

"If a larger range is needed, an alternate version can be crafted using the itertools module: takewhile(lambda x: x<stop, (start+i*step for i in count()))."
msg102370 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2010-04-05 11:48
Thanks, fixed in release26-maint r79796.
History
Date User Action Args
2010-04-05 11:48:08georg.brandlsetstatus: open -> closed
resolution: fixed
messages: + msg102370
2010-02-20 17:55:21mmsetmessages: + msg99624
2010-01-17 08:31:45mark.dickinsonsetnosy: + rhettinger
2010-01-17 01:19:10mmsetmessages: + msg97929
2010-01-17 01:09:38floxsetmessages: + msg97928
2010-01-17 00:33:49floxsetmessages: + msg97927
2010-01-16 23:50:21mmsetmessages: + msg97922
2010-01-16 23:37:35floxsetmessages: + msg97921
2010-01-16 23:07:15mmsetfiles: + irange.py

messages: + msg97918
2010-01-16 22:56:36floxsetversions: - Python 2.5
nosy: + flox

messages: + msg97917

type: behavior
stage: needs patch
2010-01-16 21:55:59mmcreate