Functional Tools

Small tools for sorting, transforming, filtering, and grouping data

Why

Functional tools help you express data flow directly: sort this, transform that, keep matching values, group related rows. They are useful when they make the operation clearer than a manual loop.

Intuition

Use sorted when you want a new ordered list, key= when the sort depends on a derived value, and lazy tools like map, filter, and itertools when values can flow one at a time.

Explanation
1. sort, sorted & key

sort mutates the list in place; sorted returns a new sorted list leaving the original unchanged. The key= argument lets you sort by any derived value.

nums = [3, 1, 4, 1, 5] nums.sort() # in place, returns None sorted(nums) # new list, nums unchanged sorted(nums, reverse=True) # [5, 4, 3, 1, 1] # key= sorts by a derived value people = [("Alice", 30), ("Bob", 25), ("Ana", 25)] sorted(people, key=lambda p: p[1]) # by age sorted(people, key=lambda p: (p[1], p[0])) # age, then name

Sort is stable: equal items keep their original order. Use key= whenever you hear "sort by".

2. map, filter & reduce

map transforms every element, filter keeps only matching elements, reduce folds a sequence into one value. All return lazy iterators — wrap in list() to materialise.

nums = [1, 2, 3, 4, 5] list(map(str, nums)) # ["1", "2", "3", "4", "5"] list(filter(lambda x: x % 2 == 0, nums)) # [2, 4] # comprehensions are clearer for inline expressions [x**2 for x in nums] [x for x in nums if x % 2 == 0] from functools import reduce from operator import add reduce(add, nums, 0) # 15

Use map with named functions, comprehensions for simple inline logic, and reduce rarely. Built-ins like sum, min, and max are usually clearer.

3. Key itertools

itertools provides composable building blocks for working with iterables — flattening, grouping, and chaining — all lazily without loading data into memory.

import itertools from operator import itemgetter # chain — flatten multiple iterables list(itertools.chain([1, 2], [3, 4])) # [1, 2, 3, 4] # groupby — group consecutive matching keys rows = [ {"dept": "eng", "name": "Ana"}, {"dept": "sales", "name": "Bo"}, {"dept": "eng", "name": "Mia"}, ] rows.sort(key=itemgetter("dept")) for dept, group in itertools.groupby(rows, key=itemgetter("dept")): print(dept, list(group))

groupby only groups consecutive matching keys, so sort by the same key first. Reach for itertools when a loop is mostly glue code.