Cheatsheet for iteration in Python.

Iterators

it = iter([1, 2, 3])
next(it)        # 1
next(it)        # 2
next(it, "done")  # 3 (default on exhaustion)

Generator function

def count_to(n):
    for i in range(n):
        yield i

for x in count_to(5):
    print(x)

Lazy; memory-efficient.

Generator expression

squares = (x**2 for x in range(10))
total = sum(x**2 for x in range(10))    # no list built

Use when you just iterate once.

Comprehensions

# List
squares = [x**2 for x in range(10)]

# Dict
by_id = {u.id: u for u in users}

# Set
unique = {x % 7 for x in numbers}

# Filtered
evens = [x for x in nums if x % 2 == 0]

# Nested
matrix = [[r * c for c in range(5)] for r in range(5)]

Generator over comprehension when you don’t need to keep the result.

Async generator

async def fetch_pages(urls):
    for u in urls:
        page = await fetch(u)
        yield page

async for page in fetch_pages(urls):
    process(page)

Async comprehension

async def all_pages(urls):
    return [page async for page in fetch_pages(urls)]

yield from (delegation)

def parent():
    yield from [1, 2, 3]
    yield from another_gen()

Equivalent to for x in inner: yield x.

Sending values into generators

def echo():
    while True:
        msg = yield
        print("got:", msg)

g = echo()
next(g)         # advance to first yield
g.send("hi")    # prints "got: hi"

Rarely used; mostly replaced by async.

itertools

from itertools import (
    count, cycle, repeat,                    # infinite
    chain, compress, dropwhile, takewhile,    # filtering
    starmap, accumulate, batched,            # transforming
    combinations, permutations, product,      # combinatorial
    groupby, islice, tee, zip_longest,        # iteration
)

# Examples
list(chain([1, 2], [3, 4]))                  # [1, 2, 3, 4]
list(batched("abcdefg", 3))                  # [("a","b","c"), ("d","e","f"), ("g",)]
list(zip_longest([1, 2], [3, 4, 5], fillvalue=0))  # [(1, 3), (2, 4), (0, 5)]

# Pairwise
from itertools import pairwise
list(pairwise([1, 2, 3, 4]))                 # [(1,2), (2,3), (3,4)]

islice (slice an iterator)

from itertools import islice

first_10 = list(islice(gen, 10))             # take first 10
window = list(islice(gen, 5, 15))            # skip 5, take 10

groupby

from itertools import groupby

# Group consecutive identical
items = [("a", 1), ("a", 2), ("b", 3), ("a", 4)]
for key, group in groupby(items, key=lambda x: x[0]):
    print(key, list(group))
# a [(a,1), (a,2)]
# b [(b,3)]
# a [(a,4)]

Note: only groups consecutive items. Sort first if you want full grouping.

takewhile / dropwhile

list(takewhile(lambda x: x < 5, [1, 2, 3, 5, 4]))    # [1, 2, 3]
list(dropwhile(lambda x: x < 5, [1, 2, 3, 5, 4]))    # [5, 4]

product (cartesian)

from itertools import product

list(product([1, 2], ["a", "b"]))     # [(1,"a"), (1,"b"), (2,"a"), (2,"b")]
list(product(range(2), repeat=3))     # [(0,0,0), (0,0,1), ..., (1,1,1)]

chain.from_iterable (flatten)

from itertools import chain

nested = [[1, 2], [3, 4], [5]]
flat = list(chain.from_iterable(nested))    # [1, 2, 3, 4, 5]

Counter

from collections import Counter

c = Counter("aabbbcccc")     # {'c': 4, 'b': 3, 'a': 2}
c.most_common(2)             # [('c', 4), ('b', 3)]

defaultdict

from collections import defaultdict

by_letter = defaultdict(list)
for word in words:
    by_letter[word[0]].append(word)

enumerate

for i, item in enumerate(items, start=1):
    print(i, item)

zip

for a, b in zip(list_a, list_b):
    ...

# strict — same length required
for a, b in zip(list_a, list_b, strict=True):
    ...

reversed / sorted

reversed([1, 2, 3])                           # iterator
sorted(items, key=lambda x: x.name)
sorted(items, key=lambda x: x.age, reverse=True)

map / filter

Often clearer as comprehensions:

# OK
list(map(str, [1, 2, 3]))

# Clearer
[str(x) for x in [1, 2, 3]]

For lazy: keep map/filter; result is iterator.

Common mistakes

  • Iterator exhausted after one pass — re-create or use tee.
  • Modifying a list while iterating — undefined behavior.
  • dict.items() then mutating — RuntimeError.
  • Comprehension that creates huge intermediate list when generator would do.

Read this next

If you want my itertools recipe library, it’s at rajpoot.dev .


Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .