what *is* a class?

Gonçalo Rodrigues op73418 at mail.telepac.pt
Tue Jun 18 21:22:50 CEST 2002


On Tue, 18 Jun 2002 15:21:38 +0200, holger krekel
<pyth at devel.trillke.net> wrote:

>Gonçalo Rodrigues wrote:
>> Here goes my personal version of this module. It is largely based off
>> Sami Hangaslammi recipe at Active State plus some additions/differences
>> of mine.
>> ...
>
>thanks. that's a good starting point to implement an iterable module. 
>I guess we all agree that iterator versions of the builtin counterparts
>should at least accept the same arguments. 
>
>    holger
>

You are absolutely right. Here goes an improved version, where besides
some errors corrected, the iterator versions now behave as the builtin
ones.

All the best,
Gonçalo Rodrigues

"""
Iterator utilities module.

Acknowledgements: Largely inspired by Iterator utilities by Sami
Hangalasmmi.
"""

#Import generators.
from __future__ import generators


__version__ = 1.1
__author__ = "G. Rodrigues"


def iterzip(*iterators):
    """Iterator version of builtin zip."""
    #Initialize variables.
    iterators = [iter(iterator) for iterator in iterators]
    while 1:
        yield tuple([i.next() for i in iterators])


def iterzipper(*iterators):
    """Second version of the builtin zip, exiting only when all the
iterators are exausted."""
    #Initialize variables.
    iterators = [iter(iterator) for iterator in iterators]
    ret = []

    while 1:
        #Emulate map behaviour.
        none_added = 0
        ret = []

        for iterator in iterators:
            try:
                ret.append(iterator.next())
            except StopIteration:
                ret.append(None)
                none_added += 1

        #Return value or exit.
        if none_added == len(iterators):
            raise StopIteration
        else:
            yield tuple(ret)


def iterfilter(func, iterator):
    """Iterator version of builtin filter."""
    #Initialize variables.
    if func is none:
        func = lambda x: x

    for elem in iterator:
        if func(elem):
            yield elem


def iterwhile(func, iterator):
    """Iterate while func(elem) is true."""
    for elem in iterator:
        if func(elem):
            yield elem
        else:
            raise StopIteration


def itermap(func, *iterators):
    """Iterator version of builtin map."""
    #Initialize variables.
    if func is None:
        func = lambda *x: x

    for elems in iterzipper(*iterators):
        yield func(*elems)


def iterconcat(*iterators):
    """Concatenates all the iterators passed as arguments."""
    for iterator in iterators:
        for elem in iterator:
            yield elem


def iterapply(iterator, *args):
    """Applies an iterator of callables iteractively to args."""
    #Initialize variables.
    arg = args
    for func in iterator:
        arg = func(*arg)
        yield arg


def iterreduce(func, iterator, default = None):
    """Lazy iterator version of reduce builtin."""
    #Initialize variables.
    iterator = iter(iterator)

    #Get first value.
    try:
        prev = iterator.next()
    except StopIteration:
        if default is not None:
            yield default
        raise StopIteration

    #Get second value.
    try:
        next = iterator.next()
    except StopIteration:
        yield prev
        raise StopIteration

    prev = func(prev, next)
    yield prev

    #Continue looping.
    for next in iterator:
        prev = func(prev, next)
        yield prev


def iterslice(iterator, slice):
    """Lazy slice of an iterator."""
    #Initialize variables.
    iterator = iter(iterator)

    if isinstance(slice,int):
        stop = slice
    else:
        stop = slice.stop
        start = slice.start or 0
        step = slice.step or 1
    
    #Skip until start if start different from 0.
    if start:
        for i in range(start):
            iterator.next()
    else:
        i = 0

    while i < stop:
        yield iterator.next()
        i += 1
        #Skip step values.
        for i in range(i + 1, i + step):
            iterator.next()
        

#More specialized iterator utilities.
def itergroup(iterator, n):
    """Iterates through iterator, yielding a list of n iterations at a
time."""
    #Initialize variables.
    ret = []

    #Read n elems at a time.
    for elem in iterator:
        ret.append(elem)
        if len(ret) == n:
            yield ret
            ret = []

    #Yield what is left.
    if not ret:
        yield ret


def itersum(iterator):
    """Returns the sum of all the elements in the iterator, None if the
iterator has no elements."""
    #Initialize variables.
    iterator = iter(iterator)
    try:
        ret = iterator.next()
    except StopIteration:
        return None
    
    for elem in iterator:
        ret += elem

    #Return result.
    return ret






More information about the Python-list mailing list