The essentials
Quick reference
One focused task per row. Jump to the related section for complete, working examples.
| Use | Syntax | Examples |
|---|---|---|
| Count hashable values | counts = Counter(values) | View examples |
| Get common values | top = counts.most_common(3) | View examples |
| Sum counts | size = counts.total() | View examples |
| Group values | groups = defaultdict(list) | View examples |
| Initialize numeric counts | counts = defaultdict(int) | View examples |
| Add to the left | queue.appendleft(item) | View examples |
| Remove from the left | item = queue.popleft() | View examples |
| Keep a bounded history | history = deque(maxlen=100) | View examples |
| Layer mappings | config = ChainMap(cli, environment, defaults) | View examples |
| Add a child scope | child = config.new_child(overrides) | View examples |
| Declare a tuple record | Point = namedtuple('Point', ['x', 'y']) | View examples |
| Copy with field changes | moved = point._replace(x=10) | View examples |
| Push onto a min-heap | heappush(heap, (priority, item)) | View examples |
| Pop the smallest entry | priority, item = heappop(heap) | View examples |
| Select a few smallest values | lowest = nsmallest(3, values) | View examples |
| Find a right insertion point | index = bisect_right(values, target) | View examples |
| Insert while sorted | insort(values, item) | View examples |
The right container makes intent visible and avoids accidental complexity. Start with built-in dict, list, set, and tuple; reach for collections when counting, grouping, layering mappings, or operating at both ends of a queue, and use heapq or bisect when you need incremental ordering without repeatedly sorting everything.
Step by step
Detailed examples
Count values and perform multiset arithmetic
Counter is a dict subclass whose missing keys read as zero. most_common preserves first-encounter order for equal counts, while arithmetic can combine inventories and drops zero or negative results from ordinary addition and subtraction outputs. Counter.total was added in Python 3.10; use sum(counter.values()) when supporting older versions.
from collections import Counter
stock = Counter(['tea', 'coffee', 'tea', 'cocoa'])
delivery = Counter(tea=1, coffee=2)
print(stock['tea'], stock['water'])
print(stock.most_common(2))
print(sorted((stock + delivery).items()))
print(stock.total()) 2 0
[('tea', 2), ('coffee', 1)]
[('cocoa', 1), ('coffee', 3), ('tea', 3)]
4Create missing values only when indexed
defaultdict calls its zero-argument factory when __getitem__ encounters a missing key, stores the result, and returns it. Methods such as get do not invoke the factory. Prefer it for uniform grouping or accumulation; use setdefault when initialization depends on the current operation, and avoid factories with surprising side effects.
from collections import defaultdict
records = [('fruit', 'pear'), ('tool', 'saw'), ('fruit', 'plum')]
groups = defaultdict(list)
for category, value in records:
groups[category].append(value)
print(dict(groups))
print(groups.get('missing'))
print('missing' in groups) {'fruit': ['pear', 'plum'], 'tool': ['saw']}
None
FalseUse deque for queues and bounded histories
deque supports append and pop operations at either end in approximately O(1) time, while removing from the front of a list shifts remaining elements. A maxlen deque keeps only the newest bounded window. Individual indexing toward the middle is slower, so use a list when random access dominates.
from collections import deque
queue = deque(['build', 'test'])
queue.appendleft('lint')
history = deque(maxlen=2)
while queue:
task = queue.popleft()
history.append(task)
print(f'run {task}')
print(list(history)) run lint
run build
run test
['build', 'test']Layer configuration without merging dictionaries
ChainMap searches its mappings from first to last, making precedence explicit while retaining live links to the originals. Writes and deletions affect only the first mapping. new_child adds a scope at the front, and parents removes the current front scope; materialize with dict only when you need an independent snapshot.
from collections import ChainMap
defaults = {'color': 'blue', 'retries': 2}
environment = {'retries': 4}
cli = {}
config = ChainMap(cli, environment, defaults)
print(config['color'], config['retries'])
config['color'] = 'green'
child = config.new_child({'retries': 1})
print(child['color'], child['retries'])
print(cli) blue 4
green 1
{'color': 'green'}Use named tuples for compact immutable records
namedtuple creates a tuple subclass, so values unpack, index, compare, and serialize like tuples while exposing readable field names. _replace returns a new value because records are immutable. For defaults, type annotations, validation, or evolving behavior, a frozen dataclass may communicate the model more clearly.
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'], defaults=[0])
origin_side = Point(4)
print(origin_side.x, origin_side.y)
x, y = origin_side
print(x + y)
print(origin_side._replace(y=3)) 4 0
4
Point(x=4, y=3)Maintain a priority queue with heapq
heapq represents a min-heap inside a list: heap[0] is the smallest entry, but the remaining list is not globally sorted. Tuples compare field by field, so include a unique counter before a non-orderable payload when priorities can tie. nsmallest and nlargest suit small selections; sorted is usually clearer when selecting most of the input.
from heapq import heappop, heappush, nsmallest
heap = []
for order, (priority, task) in enumerate([(2, 'docs'), (1, 'test'), (1, 'lint')]):
heappush(heap, (priority, order, task))
while heap:
priority, _, task = heappop(heap)
print(priority, task)
print(nsmallest(2, [8, 3, 5, 1])) 1 test
1 lint
2 docs
[1, 3]Search and update already sorted lists with bisect
bisect_left chooses the position before equal items and bisect_right chooses after them. insort performs the search efficiently, but inserting into a list remains O(n) because later elements move. It is effective for modest collections with occasional insertions; batch additions are often better followed by one sort.
from bisect import bisect_left, bisect_right, insort
scores = [10, 20, 20, 40]
print(bisect_left(scores, 20), bisect_right(scores, 20))
insort(scores, 30)
print(scores)
print(scores[bisect_left(scores, 25):]) 1 3
[10, 20, 20, 30, 40]
[30, 40]Local code tester
Schedule tasks by priority
Add priorities, inspect the heap, and compare priority processing with a bounded recent-history deque.
Press Run to load Python locally.
Sources and further reading
References
Authoritative documentation used to verify and expand this cheat sheet.
Help us improve
Found a typo or missing example?
Tell us what would make this cheat sheet clearer, more complete, or more useful.



