PART 3 · ADVANCED PYTHON · CHAPTER 10
itertools, functools and sorting
FreeLesson 34 of 78
The standard library already has the building blocks most coding rounds ask you to write by hand. Know them, then be ready to write them yourself.
from itertools import groupby
statuses = ["delivered", "cancelled", "delivered", "delivered"]
print([(k, len(list(g))) for k, g in groupby(statuses)])
print([(k, len(list(g))) for k, g in groupby(sorted(statuses))])Output
[('delivered', 1), ('cancelled', 1), ('delivered', 2)]
[('cancelled', 1), ('delivered', 3)]from itertools import (batched, islice, chain,
accumulate, pairwise)
ids = range(101, 108)
print(list(batched(ids, 3))) # Python 3.12+
print(list(islice(ids, 2, 5))) # slice any iterable
print(list(chain([1, 2], (3,), "ab"))) # glue iterables
print(list(accumulate([1198, 796, 1499]))) # running total
print(list(pairwise(["01-10", "02-02", "03-05"])))Output
[(101, 102, 103), (104, 105, 106), (107,)]
[103, 104, 105]
[1, 2, 3, 'a', 'b']
[1198, 1994, 3493]
[('01-10', '02-02'), ('02-02', '03-05')]from functools import partial, reduce
from operator import itemgetter
rows = [("Delhi", 747), ("Pune", 3498),
("Delhi", 846), ("Pune", 1598)]
# city descending, amount ascending:
# two stable sorts, least important key first
rows.sort(key=itemgetter(1))
rows.sort(key=itemgetter(0), reverse=True)
print(rows)
parse_bin = partial(int, base=2)
print(parse_bin("1010"), reduce(lambda a, b: a * b, [1, 2, 3]))Output
[('Pune', 1598), ('Pune', 3498), ('Delhi', 747), ('Delhi', 846)]
10 6| Tool | Does | Hand-written version asked in rounds |
|---|---|---|
collections.Counter | Counts items | dict with get(k, 0) + 1 |
heapq.nlargest(k, xs) | Top k without a full sort | A size-k min-heap (P2) |
collections.deque(maxlen=k) | Fixed-size sliding window | List with pop(0), which is O(n) |
functools.lru_cache | Memoize a function | dict cache, OrderedDict for LRU (P16) |
bisect.insort | Keep a list sorted on insert | Binary search by hand |
Practice before you move on
- Group the rows of orders.csv by status with itertools.groupby (sort first) and print the count per group.
- Sort the orders by status ascending and by amount descending in a single sorted() call.