Python Itertools: Recipes for Clean, Lazy Data Processing
Itertools functions write loops that are shorter, faster, and memory-efficient. These are the recipes I use most in real code. The itertools module contains functions for working with iterators in efficient, composable ways. I ignored it for years because the names sounded abstract and the documentation was dense. Once I tried a few functions, I realized they replace loops I had been writing by hand, often with better performance and lower memory use. Here are the recipes I use most. chain for Flattening One Level The chain function takes multiple iterables and yields their items in sequence. I use it to flatten a list of lists by one level without a nested loop. import itertools groups = [[1, 2, 3], [4, 5], [6, 7, 8]] flat = list(itertools.chain(*groups)) # [1, 2, 3, 4, 5, 6, 7, 8] # chain.from_iterable avoids the unpacking flat = list(itertools.chain.from_iterable(groups)) I prefer chain.from_iterable when the groups come from a generator, because it does not require unpacking the outer iterable into arguments. The result is lazy, so flattening a large generator does not load everything into memory. combinations and permutations The combinations function yields all r-length…