filter iterable based on predicate take from another iterable

James Stroud jstroud at mbi.ucla.edu
Wed Dec 10 05:44:11 EST 2008


Peter Otten wrote:
> bernhard.voigt at gmail.com wrote:
> 
>> is there is a neat way to select items from an iterable based on
>> predicates stored in another iterable without zipping? I can do
>> something like this:
>>
>> import itertools
>> foo = range(10)
>> # select even numbers
>> bar = map(lambda i: i%2, foo)
>> foobarselected = itertools.ifilterfalse(lambda t: t[0], itertools.izip
>> (bar,foo))
>> # for simplicity I want to work with the single item list, not the
>> zipped one
>> fooselected = list(t[1] for t in foobarselected)
>>
>> However, it would be nice to have a function combining the last two
>> instructions. Something like
>> itertools.ifilterother(bar, foo) -> yield iterator with items from foo
>> where bar is true
> 
> I think it's a good approach to keep the number of primitives low. I find
> the list comprehension combined with izip() quite readable:
> 
> [v for f, v in izip(bar, foo) if not f(v)]
> 
> Peter

If you want an iterator without requiring making a list, you can simply 
use parentheses instead of brackets:

agenerator = (v for f, v in izip(bar, foo) if not f(v))

This is perfectly lazy but not immune to problems when foo or bar is 
changed before the generator is fully consumed.

James



-- 
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com



More information about the Python-list mailing list