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