Python Standard Library Cheat Sheet (Page 1 of 2)
collections
Counter
from collections import Counter
c = Counter("abracadabra") # Counter({'a':5,'b':2,'r':2,'c':1,'d':1})
c.most_common(2) # [('a',5),('b',2)]
c['z'] # 0 (missing keys return 0)
c.update("aaa") # add counts
c.subtract(Counter("a")) # subtract counts
c1 + c2 # combine counts (drops zero/neg)
c1 - c2 # subtract (drops zero/neg)
c1 & c2 # min of each count
c1 | c2 # max of each count
list(c.elements()) # iterator of elements repeated by count
+c # drop zero/negative counts
defaultdict
from collections import defaultdict
g = defaultdict(list) # missing key -> []
g[0].append(1) # no KeyError
d = defaultdict(int) # missing key -> 0
d = defaultdict(set) # missing key -> set()
d = defaultdict(lambda: float('inf'))
deque
from collections import deque
dq = deque([1,2,3], maxlen=5) # optional maxlen (auto-evicts)
dq.append(4) # right append O(1)
dq.appendleft(0) # left append O(1)
dq.pop() # right pop O(1)
dq.popleft() # left pop O(1)
dq.rotate(1) # rotate right: [3,1,2]
dq.rotate(-1) # rotate left: [2,3,1]
dq.extend([5,6]) # right extend
dq.extendleft([5,6]) # left extend (reverses order)
OrderedDict
from collections import OrderedDict
od = OrderedDict()
od['a'] = 1; od['b'] = 2
od.move_to_end('a') # move to end
od.move_to_end('a', last=False) # move to front
od.popitem(last=True) # pop from end (LIFO)
od.popitem(last=False) # pop from front (FIFO)
# LRU cache pattern: move_to_end on access, popitem(last=False) to evict
ChainMap
from collections import ChainMap
defaults = {'color': 'red', 'size': 10}
overrides = {'color': 'blue'}
cm = ChainMap(overrides, defaults)
cm['color'] # 'blue' (first found wins)
cm['size'] # 10
cm.maps # [overrides, defaults] - mutable list
import itertools as it
# COMBINATORIC
it.product('AB','xy') # Ax Ay Bx By (cartesian product)
it.product(range(3), repeat=2) # 00 01 02 10 11 12 20 21 22
it.permutations('ABC', 2) # AB AC BA BC CA CB (n!/(n-r)!)
it.combinations('ABC', 2) # AB AC BC (nCr)
it.combinations_with_replacement('ABC', 2) # AA AB AC BB BC CC
# INFINITE
it.count(10, 2) # 10, 12, 14, 16, ...
it.cycle('AB') # A, B, A, B, ...
it.repeat(5, 3) # 5, 5, 5
# TERMINATING
it.chain([1,2], [3,4]) # 1, 2, 3, 4 (flatten one level)
it.chain.from_iterable([[1,2],[3,4]]) # same
it.accumulate([1,2,3,4]) # 1, 3, 6, 10 (running sum)
it.accumulate([3,1,4], max) # 3, 3, 4 (running max)
it.accumulate([3,1,4], min) # 3, 1, 1 (running min)
list(it.groupby('AAABBC')) # [(A,[A,A,A]),(B,[B,B]),(C,[C])]
# MUST sort first if groups aren't contiguous
it.islice(range(100), 5) # first 5 elements
it.islice(range(100), 2, 8, 2) # [2, 4, 6] (start, stop, step)
it.takewhile(lambda x: x<5, [1,3,6,2]) # [1, 3]
it.dropwhile(lambda x: x<5, [1,3,6,2]) # [6, 2]
it.starmap(pow, [(2,3),(3,2)]) # [8, 9]
it.compress('ABCDE', [1,0,1,0,1]) # A, C, E
it.filterfalse(lambda x: x%2, range(10)) # 0,2,4,6,8
it.zip_longest([1,2],[3,4,5], fillvalue=0) # (1,3),(2,4),(0,5)
it.pairwise([1,2,3,4]) # (1,2),(2,3),(3,4) # Python 3.10+
it.batched('ABCDEFG', 3) # ABC DEF G # Python 3.12+
from functools import lru_cache, cache, reduce, partial
@lru_cache(maxsize=None) # unbounded memoization
def fib(n):
return n if n < 2 else fib(n-1) + fib(n-2)
@cache # Python 3.9+, same as lru_cache(maxsize=None)
def expensive(x, y): ...
# WARNING: lru_cache args must be HASHABLE (no lists/dicts/sets)
# Convert: tuple(lst), frozenset(s), tuple(sorted(d.items()))
reduce(lambda a, b: a + b, [1,2,3,4]) # 10
reduce(lambda a, b: a * b, [1,2,3,4]) # 24
reduce(lambda a, b: a + b, [1,2,3], 100) # 106 (with initial)
add5 = partial(lambda x, y: x + y, 5)
add5(3) # 8
# singledispatch: generic function overloading by first arg type
from functools import singledispatch
@singledispatch
def process(arg): print(f"default: {arg}")
@process.register(int)
def _(arg): print(f"int: {arg}")
Python Standard Library Cheat Sheet (Page 2 of 2)
heapq (min-heap only)
import heapq
h = []
heapq.heappush(h, 5) # push element O(log n)
heapq.heappush(h, (1, 'task')) # push tuple (priority, value)
val = heapq.heappop(h) # pop smallest O(log n)
h[0] # peek at smallest O(1)
heapq.heapify(lst) # convert list to heap O(n)
heapq.heapreplace(h, val) # pop then push (more efficient)
heapq.heappushpop(h, val) # push then pop (more efficient)
heapq.nlargest(3, lst) # 3 largest O(n log k)
heapq.nsmallest(3, lst) # 3 smallest O(n log k)
heapq.nlargest(3, lst, key=lambda x: x[1]) # with key func
heapq.merge(*sorted_iters) # merge sorted iterables O(n log k)
# MAX HEAP: negate values
heapq.heappush(h, -val) # push negated
-heapq.heappop(h) # pop and negate back
# Custom objects: use tuple (priority, tiebreaker, object)
# or implement __lt__ on your class
bisect (binary search on sorted lists)
import bisect
a = [1, 3, 3, 5, 7]
bisect.bisect_left(a, 3) # 1 (leftmost insertion point)
bisect.bisect_right(a, 3) # 3 (rightmost insertion point)
bisect.bisect(a, 3) # 3 (alias for bisect_right)
bisect.insort_left(a, 4) # insert maintaining sort O(n)
bisect.insort_right(a, 4) # insert maintaining sort O(n)
# Find index of value (exact match)
i = bisect.bisect_left(a, x)
found = i < len(a) and a[i] == x
# Find leftmost value >= x
i = bisect.bisect_left(a, x) # a[i] >= x (or i == len(a))
# Find rightmost value <= x
i = bisect.bisect_right(a, x) - 1 # a[i] <= x (or i == -1)
# Count occurrences of x in sorted list
lo = bisect.bisect_left(a, x)
hi = bisect.bisect_right(a, x)
count = hi - lo
math
import math
math.gcd(12, 8) # 4
math.lcm(4, 6) # 12 (Python 3.9+)
math.gcd(12, 8, 6) # 2 (multi-arg, Python 3.9+)
math.comb(5, 2) # 10 (5 choose 2, i.e., nCr)
math.perm(5, 2) # 20 (nPr)
math.factorial(5) # 120
math.inf # positive infinity
-math.inf # negative infinity
math.ceil(3.2) # 4
math.floor(3.8) # 3
math.log(8, 2) # 3.0
math.log2(8) # 3.0 (more precise than log(x,2))
math.log10(1000) # 3.0
math.sqrt(16) # 4.0
math.isqrt(10) # 3 (integer sqrt, Python 3.8+)
math.pow(2, 10) # 1024.0 (float)
math.prod([1,2,3,4]) # 24 (Python 3.8+)
math.copysign(1, -3) # -1.0
math.isinf(x), math.isnan(x)
String Methods Quick Reference
s = "hello world"
s.split() # ['hello', 'world']
s.split(',', maxsplit=1) # split on comma, max 1 split
s.rsplit(',', 1) # split from right
s.strip() # strip whitespace both sides
s.lstrip('h') # strip from left
s.rstrip('d') # strip from right
s.replace('l', 'L', 1) # replace first occurrence
s.find('lo') # 3 (index, or -1 if not found)
s.index('lo') # 3 (raises ValueError if not found)
s.rfind('l') # 9 (rightmost)
s.count('l') # 3
s.startswith('he') # True
s.endswith(('d','s')) # True (tuple of suffixes)
s.isalpha(), s.isdigit(), s.isalnum()
s.upper(), s.lower(), s.title(), s.capitalize(), s.swapcase()
s.zfill(15) # '0000hello world'
','.join(['a','b','c']) # 'a,b,c'
s.partition(' ') # ('hello', ' ', 'world')
s.rpartition(' ') # ('hello', ' ', 'world')
chr(97) # 'a'
ord('a') # 97
sorted() and Sorting
sorted(lst) # ascending
sorted(lst, reverse=True) # descending
sorted(lst, key=lambda x: x[1]) # by second element
sorted(lst, key=lambda x: (-x[0], x[1]))# primary desc, secondary asc
sorted(s, key=str.lower) # case-insensitive
# Custom comparator (cmp_to_key)
from functools import cmp_to_key
def compare(a, b): # return negative/zero/positive
return (a > b) - (a < b) # standard 3-way compare
sorted(lst, key=cmp_to_key(compare))
# Stable sort: equal elements keep original order
# list.sort() is in-place, sorted() returns new list
# Both use Timsort: O(n log n) worst, O(n) when nearly sorted
# Sort dict by value
sorted(d.items(), key=lambda x: x[1])
Useful Built-ins Reminder
zip(a, b) # pair elements, stops at shorter
enumerate(lst, start=0) # (index, value) pairs
map(fn, iterable) # apply fn to each element
filter(fn, iterable) # keep elements where fn is truthy
any(iterable) # True if any truthy
all(iterable) # True if all truthy
min(a, key=..., default=...) # min with key func and default
max(a, key=..., default=...) # max with key func and default
sum(iterable, start=0) # sum with optional start
abs(-5) # 5
divmod(17, 5) # (3, 2) (quotient, remainder)
pow(2, 10, MOD) # modular exponentiation (fast)
isinstance(x, (int, float)) # type check
float('inf'), float('-inf')
int('1010', 2) # 10 (binary string to int)
bin(10) # '0b1010'
bin(10).count('1') # popcount = 2