PEP 234: Iterators

Tim Peters tim.one at home.com
Wed May 2 18:47:22 EDT 2001


[Peter Caven]
> ...
> I would really like to be able to write a loop over only the keys,
> values or items in a dict that pass some test (filter):
>
> for KeyFilter(),value  in dict:
>   ...do something with the values that have keys that pass the filter.
>
> I know this idea is half-baked.  Is there some other way of elegantly
> doing this without doing an explicit test inside the loop?

List comprehensions support iteration + filtering directly, but materialize
the whole result in one gulp.  The following works fine in current CVS
Python, expoiting the proposed new 2.2 iterator gimmicks:

class filteriter:
    def __init__(self, filter, obj):
        self.filter = filter
        self.get = iter(obj).next

    def __iter__(self):
        return self

    def next(self):
        while 1:
            obj = self.get()
            if self.filter(obj):
                return obj

d = {1:2, 2:3, 3:4, 4:5}

for k in filteriter(lambda k: k & 1 == 0, d):
    print "even key", k  # prints 2 and 4

for v in filteriter(lambda k: k & 1, d.itervalues()):
    print "odd value", v # prints 3 and 5

evenkeys = filteriter(lambda k: k & 1 == 0, d)
bigevenkeys  = filteriter(lambda k: k > 2, evenkeys)

for whee in bigevenkeys:
    print whee # prints 4

I think it should be clear that an iterator can support any computation
whatsoever, including filtering, transforming, stuttering, ..., whatever you
can dream up.  Plus they can be chained together (as in bigevenkeys above).





More information about the Python-list mailing list