"""Clean Code in Python - Chapter 7: Using Generators > Idiomatic Iteration with itertools """ import logging from itertools import filterfalse, tee logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) class IteratorWrapper: def __init__(self, iterable): self.iterable = iter(iterable) def __next__(self): value = next(self.iterable) logger.debug( "%s Producing next value: %r", self.__class__.__name__, value ) return value def __iter__(self): return self def partition(condition, iterable): """Return 2 new iterables true_cond, false_cond = partition(condition, iterable) * in true_cond, condition is true over all elements of iterable * in false_cond, condition is false over all elements of iterable """ for_true, for_false = tee(iterable) return filter(condition, for_true), filterfalse(condition, for_false) iterable = IteratorWrapper( {"name": f"element_{i}", "index": i} for i in range(20) ) def is_even(record): return record["index"] % 2 == 0 def show(records): return ", ".join(e["name"] for e in records) if __name__ == "__main__": even, odd = partition(is_even, iterable) logger.info( "\n\tEven records: %s\n\t Odd records: %s", show(even), show(odd) )