Python's unpacking syntax extends well beyond simple two-value tuples, letting you destructure lists, tuples, and even nested structures directly into named variables.
a, b, c = 1, 2, 3 # basic multiple assignment
a, b = b, a # classic Python swap trick — no temp variable needed
first, *rest = [1, 2, 3, 4, 5] # first=1, rest=[2,3,4,5] — * collects the remainder
*init, last = [1, 2, 3, 4, 5] # init=[1,2,3,4], last=5
first, *middle, last = [1, 2, 3, 4, 5] # first=1, middle=[2,3,4], last=5
(x, y), z = (1, 2), 3 # nested unpacking
for name, (age, city) in [("Rahim", (25, "Dhaka"))]: # unpack inside a loop
print(name, age, city)
a, b = b, a is Python's idiomatic way to swap two variables — it works because the right-hand side is fully evaluated into a temporary tuple before any assignment happens, so no separate temp variable is ever needed, unlike the three-line swap required in C.
The * (star) operator in an unpacking assignment collects "everything else" into a list — first, *rest = [...] is especially common when processing a sequence where the first element is special (a header row, a command name) and the rest need to be handled as a group. Unpacking can be nested to match nested data structures, and works inside a for loop's target as well, which is exactly how iterating over a dict.items() (yielding (key, value) tuples) lets you write for key, value in d.items(): directly.