what *is* a class?

Gonçalo Rodrigues op73418 at mail.telepac.pt
Tue Jun 18 07:59:21 EDT 2002


On Tue, 18 Jun 2002 13:11:04 +0200, holger krekel
<pyth at devel.trillke.net> wrote:

>Delaney, Timothy wrote:
>> > From: holger krekel [mailto:pyth at devel.trillke.net]
>> > 
>> > I agree that this is a good thing. But it wouldn't hurt to have
>> > 
>> >     reverse, sort, extend
>> > 
>> > as standalone functions somewhere in the stdlib.  They would return
>> > a copy...
>> 
>> Personally, I think this is a great idea. But I would exclude extend.
>
>I'd even like to have something like extend (see below) ...
>
>> I think there should be a library of "iterable" functions (perhaps in
>> builtins ;) which return an iterator, and accept any iterable (where
>> appropriate). Let's call it builtin module iterable (or maybe iterator ...).
>> Functions defined in this module would be specified to not modify the
>> original iterable (indeed, should all call iter(iterable) before doing
>> anything). Of course, whee appropriate a function passed in could modify the
>> original.
>> 
>> Examples of such functions would be:
>> 
>> iterable.sort(iterable [, func])
>> iterable.reverse(iterable)
>
>that would be quite expensive for common cases (like lists).  reverse and 
>sort should also allow to operate on complete sequence types. 
>iterable.reverse could be cheap again then and iterable.sort would be
>as expensive as it is now (but not requiring any inplace-steps).
>
>> iterable.map(func, iterable, ...)
>> iterable.filter(func, iterable, ...)
>> iterable.reduce(func, iterable, ...)
>> iterable.zip(iterable, ...)
>> iterable.range([start,] stop[, step])
>
>yes, indeed! i'd probably do 'from iterable import *' :-)
>
>seriously, i'd include something like concat as an iterable, too: 
>
>    for item in iterable.concat(iter1,iter2):
>        # items iterates with iter1, then iter2 
>
>All the the iterable functions should accept sequence and 
>possibly mapping types (same semantics as for 'for'-loops now).
>
>> There have been suggestions like this before, but I don't recall one for
>> sort() and reverse(), and these two have fired me :)
>
>I think an iterable module should be done. Although there would 
>inevitably be overlapping functionality with the current builtins.
>
>Maybe something for the train ride to EuroPython :-)
>
>> Tim Delaney
>
>    holger krekel
>
>
>

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.

"""
Iterator utilities module.

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

#Import generators.
from __future__ import generators


__version__ = 1.0
__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 iterfilter(iterator, func = lambda x: x):
    """Iterator version of builtin filter."""
    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 = lambda *x: x, *iterators):
    """Iterator version of builtin map. No padding is done."""
    for tupleelems in iterzip(iterators):
        yield func(*tupleelems)


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 not default:
            yield default
        raise StopIteration

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

    #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:
        if len(ret) == n:
            yield ret
            ret = []
        else:
            ret.append(elem)

    #Yield if something 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