[Python-ideas] Add irange with large integer step support to itertools

Martin Manns mmanns at gmx.net
Fri Jan 7 11:24:35 CET 2011


Hi

I would like to propose an addition of an "irange" function to
itertools. This addition could reduce testing effort when developing
applications, in which large integers show up.

Both, xrange (Python 2.x) and range (Python 3.x) have limited support
for large integer step values, for example:

Python 3.1.3 (r313:86834, Nov 28 2010, 10:01:07) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> range(10**10000, 10**10000+10**1000, 10**900)[5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: Python int too large to convert to C ssize_t

The code below is untested and for clarification only. 
It has been taken and modified from
[issue7721] http://bugs.python.org/issue7721

With irange, no OverflowError is thrown:

>>> from itertools import islice
>>> from irange import irange
>>> def nth(iterable, n, default=None):
...     "Returns the nth item or a default value"
...     return next(islice(iterable, n, None), default)
... 
>>> nth(irange(10**10000, 10**10000+10**1000, 10**900), 5)
100000000000000 ...


## Code snippet (untested)

from itertools import count, takewhile

def irange(start, stop=None, step=1):
    """Range for long integers
    
    Usage: irange([start], stop, [step])
    
    Parameters
    ----------
    start: Integer
    stop: Integer
    step: Integer, defaults to 1
    
    """
    
    if start is None:
        raise TypeError("range() integer argument expected, got NoneType")
    
    if stop is None:
        stop = start
        start = 0
    
    if step is None:
        step = 1
    
    if step > 0:
        if stop < start:
            return (_ for _ in [])
        cond = lambda x: x < stop
        
    elif step < 0:
        if stop > start:
            return (_ for _ in [])
        cond = lambda x: x > stop
        
    else:
        raise ValueError("irange() step argument must not be zero")
    
    return takewhile(cond, (start + i * step for i in count()))

## End code snippet


Does such an addition make sense in your eyes?


Regards

Martin




More information about the Python-ideas mailing list