Search code examples
pythonfiltergeneratordata-partitioning

Nicest, efficient way to get result tuple of sequence items fulfilling and not fulfilling condition


(This is professional best practise/ pattern interest, not home work request)

  • INPUT: any unordered sequence or generator items, function myfilter(item) returns True if filter condition is fulfilled

  • OUTPUT: (filter_true, filter_false) tuple of sequences of original type which contain the elements partitioned according to filter in original sequence order.

How would you express this without doing double filtering, or should I use double filtering? Maybe filter and loop/generator/list comprehencion with next could be answer?

Should I take out the requirement of keeping the type or just change requirement giving tuple of tuple/generator result, I can not return easily generator for generator input, or can I? (The requirements are self-made)

Here test of best candidate at the moment, offering two streams instead of tuple

import itertools as it
from sympy.ntheory import isprime as myfilter

mylist = xrange(1000001,1010000,2)
left,right = it.tee((myfilter(x), x) for x in mylist)
filter_true = (x for p,x in left if p)
filter_false = (x for p,x in right if not p)

print 'Hundred primes and non-primes odd  numbers'
print  '\n'.join( " Prime %i, not prime %i" %
                  (next(filter_true),next(filter_false))
                  for i in range(100))

Solution

  • Here is a way to do it which only calls myfilter once for each item and will also work if mylist is a generator

    import itertools as it
    left,right = it.tee((myfilter(x), x) for x in mylist)
    filter_true = (x for p,x in left if p)
    filter_false = (x for p,x in right if not p)