Unpacking & Star Expressions
Unpacking is assigning the elements of an iterable to multiple variables at once — like a, b, c = [1, 2, 3] — and star expressions let one variable scoop up the rest.
Learn Unpacking & Star Expressions in our free Python course — an interactive lesson with runnable examples, a practice exercise and a quick reference.
Part of the free Python course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
These destructuring tricks make code read like the data it handles: swapping values, splitting a list into head and tail, and spreading collections into function calls and merged dicts.
Assign several variables from one iterable in a single line. The counts must match — and swapping values becomes a one-liner:
A starred name scoops up however many items are left over into a list . It can go at the start, middle, or end:
Exactly one star is allowed per assignment. The starred variable always becomes a list , even when it captures a single item or nothing at all.
The same star syntax works into a function call: * spreads an iterable as positional args, ** spreads a dict as keyword args:
Unpacking patterns can mirror nested structure, pulling apart tuples inside tuples in one go:
The shape of the target on the left must match the shape of the data on the right. When it does, deeply structured data falls neatly into named variables.
Replace each ___ with the right unpacking target so the output matches.
✅ Match the count exactly, or use a star: a, b, *rest = [1, 2, 3] .
✅ Only one star is allowed per target. Python can't tell where one greedy group ends and the next begins.
✅ A starred target is always a list , even when unpacking a tuple. Convert with tuple(rest) if you need one.
Use unpacking, stars, and a dict merge to process structured records.
Go deeper with the official Python documentation:
Lesson complete — destructuring mastered!
You can unpack tuples and lists, swap without a temp, scoop up the rest with a star, spread *args and **kwargs into calls, merge dicts with {' '} , and destructure nested data.
🚀 Up next: Sorting with sorted() & key — order data any way you like with a custom key function.
Practice quiz
What does do?
- Assigns the whole list to a
- Raises an error because you cannot unpack a list
- Assigns 1 to a, 2 to b, and 3 to c
Answer: Assigns 1 to a, 2 to b, and 3 to c. Unpacking assigns each element of the iterable to the matching variable, as long as the counts match.
How do you swap two variables without a temporary variable?
- a, b = b, a
- swap(a, b)
- a = b; b = a
- a, b = a, b
Answer: a, b = b, a. a, b = b, a builds a tuple on the right and unpacks it on the left, swapping the values in one line.
After , what is rest?
- (2, 3, 4, 5)
- 5
The starred name captures all leftover items into a list, so rest is [2, 3, 4, 5] and first is 1.
What type is the starred target, even when unpacking a tuple?
- tuple
- list
- set
- str
Answer: list. A starred target is always a list — e.g. first, *rest = (1, 2, 3) makes rest the list [2, 3]. Use tuple(rest) if you need a tuple.
How many starred targets are allowed in a single unpacking assignment?
- Exactly one
- Up to two
- Any number
- Zero — stars are not allowed
Answer: Exactly one. Only one star is allowed per target; is a SyntaxError because Python cannot tell where one greedy group ends.
What does do when parts = ['Ada', 'wizard', 9]?
- Passes the list as a single argument
- Passes parts as keyword arguments
- Spreads the list as positional arguments: make('Ada', 'wizard', 9)
- Raises a TypeError
Answer: Spreads the list as positional arguments: make('Ada', 'wizard', 9). In a call, * unpacks an iterable into separate positional arguments, so make(*parts) is the same as make('Ada', 'wizard', 9).
What does do when config = {'name': 'Ben', 'role': 'knight', 'level': 5}?
- Passes the dict as one positional argument
- Spreads the dict as keyword arguments: make(name='Ben', role='knight', level=5)
- Passes only the dict's keys
- Merges config into make
Answer: Spreads the dict as keyword arguments: make(name='Ben', role='knight', level=5). In a call, ** unpacks a dict into keyword arguments, so make(**config) is make(name='Ben', role='knight', level=5).
What is the result of ?
- {'size': 'M', 'color': 'black'}
- size
- M
- L
Answer: L. When merging with **, later keys win on conflict, so the second dict's size 'L' overrides the first dict's 'M'.
What does produce?
The * spread expands each list inline, flattening them into a single list [1, 2, 3, 4].
Why does raise an error?
- Lists cannot be unpacked, only tuples can
- Variables must be declared first
- Too many values to unpack — counts must match (or use a star)
- The list is too long for memory
Answer: Too many values to unpack — counts must match (or use a star). Without a star, the number of targets must equal the number of values. Use a, b, *rest = [1, 2, 3] when lengths differ.