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