PEP 3132 in 90 seconds — first, *middle, last = list
Splat-unpacking — one of Python's most-used 1-liners.
Pre-3.0, splitting an iterable into head/tail meant explicit slicing: ```python items = [1, 2, 3, 4, 5] first = items[0] middle = items[1:-1] last = items[-1] ``` Three lines, three index lookups, brittle on empty/short input. PEP 3132 (Python 3.0, 2008) added the `*` operator to assignment targets so the same split is one line:
```python first, *middle, last = [1, 2, 3, 4, 5] # first=1 middle=[2, 3, 4] last=5 ``` The starred name collects EVERYTHING the other targets didn't claim. It works in function args (`def f(head, *tail):`), in `for` loops (`for first, *rest in pairs:`), in nested unpacking (`((a, b), *rest) = ...`). It's the bones of half the iteration code in any large Python codebase — and most devs never realised it was a deliberate language-level decision.
items = [1, 2, 3, 4, 5]
# Manual three-line split
first = items[0]
middle = items[1:-1]
last = items[-1]
# In a function — pre-PEP-3132 you'd unpack manually too
def first_and_rest(items):
return items[0], items[1:]# One line — readable, intent-explicit
first, *middle, last = [1, 2, 3, 4, 5]
# Function signatures get the same treatment
def show(head, *tail):
return f"head={head}, tail={tail}"
# Nested — the * can sit anywhere in the target list
((a, b), *rest) = ((10, 20), 30, 40)
# In a for-loop — destructures the iterable AND the starred middle
for first, *middle, last in [(1, 2, 3), (10, 20, 30, 40, 50)]:
print(first, middle, last)🎯 Predict the output
What does this print? `*middle` greedy-collects everything between `first` and `last`.
first, *middle, last = [1, 2, 3, 4, 5]
print(first, middle, last)
def show(head, *tail):
return f"head={head}, tail={tail}"
print(show(*[1, 2, 3, 4]))
((a, b), *rest) = ((10, 20), 30, 40)
print(a, b, rest)