Python 3000 idea -- + on iterables -> itertools.chain

George Sakkis george.sakkis at gmail.com
Sun Nov 12 21:34:26 EST 2006


Fredrik Lundh wrote:

> John Reese wrote:
>
> > It seems like it would be clear and mostly backwards compatible if the
> > + operator on any iterables created a new iterable that iterated
> > throught first its left operand and then its right, in the style of
> > itertools.chain.
>
> you do know that "iterable" is an informal interface, right?  to what
> class would you add this operation?
>
> </F>

The base object class would be one candidate, similarly to the way
__nonzero__ is defined to use __len__, or __contains__ to use __iter__.

Alternatively, iter() could be a wrapper type (or perhaps mixin)
instead of a function, something like:

from itertools import chain, tee, islice

import __builtin__
_builtin_iter = __builtin__.iter

class iter(object):

    def __init__(self, iterable):
        self._it = _builtin_iter(iterable)

    def __iter__(self):
        return self
    def next(self):
        return self._it.next()

    def __getitem__(self, index):
        if isinstance(index, int):
            try: return islice(self._it, index, index+1).next()
            except StopIteration:
                raise IndexError('Index %d out of range' % index)
        else:
            start,stop,step = index.start, index.stop, index.step
            if start is None: start = 0
            if step is None: step = 1
            return islice(self._it, start, stop, step)

    def __add__(self, other):
        return chain(self._it, other)
    def __radd__(self,other):
        return chain(other, self._it)

    def __mul__(self, num):
        return chain(*tee(self._it,num))

    __rmul__ = __mul__

__builtin__.iter = iter


if __name__ == '__main__':
    def irange(*args):
        return iter(xrange(*args))

    assert list(irange(5)[:3]) == range(5)[:3]
    assert list(irange(5)[3:])  == range(5)[3:]
    assert list(irange(5)[1:3]) == range(5)[1:3]
    assert list(irange(5)[3:1]) == range(5)[3:1]
    assert list(irange(5)[:])   == range(5)[:]
    assert irange(5)[3]         == range(5)[3]

    s = range(5) + range(7,9)
    assert list(irange(5) + irange(7,9)) == s
    assert list(irange(5) +  range(7,9)) == s
    assert list(range(5)  + irange(7,9)) == s

    s = range(5) * 3
    assert list(irange(5) * 3) == s
    assert list(3 * irange(5)) == s


George




More information about the Python-list mailing list