+This module provides splitBy function which splits a sequence into two
+subsequences, in single pass and preserving order.
+>>> def odd(x): return x%2 != 0
+>>> odds, evens = splitBy(odd, range(10))
+from collections import deque
+__author__ = "Sergey Astanin"
+ Lazily process a sequence in single pass and split into two.
+ Computes both output sequences even if only one of them is consumed.
+ def __init__(self, condition, sequence):
+ self.seq = iter(sequence)
+ def getNext(self, getGood=True):
+ these, those, cond = self.goods, self.bads, self.cond
+ these, those, cond = self.bads, self.goods, lambda x: not self.cond(x)
+ while 1: # exit on StopIteration
+def splitBy(condition, sequence):
+ Split a sequence into two subsequences, in single-pass and preserving order.
+ condition a function; if condition is None, split true and false items
+ sequence an iterable object
+ Return a pair of generators (seq_true, seq_false). The first one
+ builds a subsequence for which the condition holds, the second one
+ builds a subsequence for which the condition doesn't hold.
+ As the function works in single pass, it leads to build-up of both
+ subsequences even if only one of them is consumed.
+ cond = condition if condition else bool # evaluate as bool if condition == None
+ ss = SplitSeq(cond, sequence)
+ yield ss.getNext(getGood=True)
+ yield ss.getNext(getGood=False)
+if __name__ == "__main__":