You already know how to add items to the end of a list with
append(). But what if you want to take them off in a specific order? Python gives you a few patterns for that: stacks, queues, priority queues, and sorted lists kept in order with bisect. Each one fits a different real-world problem.Stacks: last-in, first-out
# An undo history is a stack.
# Push actions onto the top; pop them off in reverse order.
history = []
history.append('typed "hello"') # push
history.append('deleted line 2') # push
last_action = history.pop() # take most recent back -> 'deleted line 2'
print(last_action)append() adds to the end, pop() removes from the end. Together they make a stack. Think of a stack of plates: you put one on top, take one off the top. The most recent item is always first out.Queues and why list.pop(0) is slow
# collections.deque (double-ended queue) fixes this.
from collections import deque
queue = deque()
queue.append('task A') # add to the right
first = queue.popleft() # remove from the left -> 'task A'
print(first)append() and popleft() on a deque take the same short time however long the queue gets. You can also cap the size with maxlen: older items drop off automatically.# Keep only the newest 3 log lines.
from collections import deque
log = deque(maxlen=3)
for msg in ['boot', 'login', 'error', 'retry']:
log.append(msg)
print(list(log)) # -> ['login', 'error', 'retry']Priority queues with heapq
# A priority queue always hands back the most urgent task.
import heapq
heap = []
# (priority, label) — smaller number means more urgent
heapq.heappush(heap, (2, 'send email'))
heapq.heappush(heap, (1, 'fix crash')) # highest priority
heapq.heappush(heap, (3, 'write report'))
top = heapq.heappop(heap) # -> (1, 'fix crash')
print(top)heapq turns a plain list into a min-heap. heappush adds an item, heappop removes and returns the smallest one. Because Python compares tuples left-to-right, storing (priority, task) gives you exactly what you want: lowest priority number first.# Grab the 3 smallest without sorting the whole list yourself.
import heapq
scores = [85, 42, 91, 73, 60]
lowest_3 = heapq.nsmallest(3, scores)
print(lowest_3) # -> [42, 60, 73]Keeping a list sorted with bisect
# insort keeps a list in order as you add values.
import bisect
scores = []
bisect.insort(scores, 85)
bisect.insort(scores, 42) # -> [42, 85]
bisect.insort(scores, 91) # -> [42, 85, 91]
print(scores)bisect.bisect_right(sorted_list, value) tells you where a new item would fit. That makes it easy to map a raw number onto bands — like turning an exam score into a letter grade.# Turn a numeric score into a band.
import bisect
breakpoints = [40, 60, 80, 90] # F | D | C | B | A edges
def grade(score):
idx = bisect.bisect_right(breakpoints, score)
return 'FDCBA'[idx]
print(grade(72)) # -> 'C'