What does `first, *rest = items` bind in Python, and where may the star appear?
answer
- The leftover target has a fixed type
- It is always the same container type
- Position is free, count is not
- Fixed targets set a minimum, not an exact
- Empty leftovers are legal, not an error
basics
~20 sfirst takes one value and rest takes every remaining value as a list — always a list, whatever the right-hand side was. At most one starred target is allowed, and it may sit anywhere in the target list.
solid answer
~50 sA starred target (PEP 3132) absorbs however many values the fixed targets do not claim, and it always binds a `list` — even when the right-hand side is a tuple, a string or a generator. The star may appear anywhere in the target list, so `*init, last = xs` and `head, *middle, tail = xs` are both legal, but only one star per target list; two raise `SyntaxError: multiple starred expressions in assignment`. The non-starred targets set a minimum: `a, b, *c = [1]` raises `ValueError: not enough values to unpack (expected at least 2, got 1)`, while the starred name happily binds an empty list when there is nothing left over. The same form works as a `for` target, so `for kind, *tags in rows:` handles rows of differing width. Because it must know the total count, the assignment consumes the iterable eagerly.
code
python · 8 linesfirst, *rest = [10, 20, 30]
print(first, rest) # 10 [20, 30]
*init, last = "chat"
print(init, last) # ['c', 'h', 'a'] t
a, *mid, z = (1, 2)
print(a, mid, z) # 1 [] 2go deeper
Recall the shape and the type: the star soaks up whatever is left and the name it binds is a list. Know that first, *rest = [] is an error while first, *rest = [1] gives an empty rest.
Explain the mechanics an interviewer is really after: one star per target list, any position, fixed targets set a minimum rather than an exact count, and the leftover is materialised as a list regardless of the source type.
Demonstrate the cost. Say out loud that the form exhausts an iterator, that *_ saves nothing, and that head/tail recursion over a sequence is quadratic — then name what you would write instead in hot or streaming code.
Own where destructuring belongs in a codebase's style. Variable-width positional records are a schema smell; decide whether the fix is a starred target at one boundary or a named structure that removes the variability entirely.
### What the star means Extended iterable unpacking, added by PEP 3132 and available in every Python 3 release including 3.14, lets exactly one target in a target list be prefixed with `*`. The fixed targets each claim one value, in position; the starred target claims everything left over. `first, *rest = [10, 20, 30]` binds `first` to `10` and `rest` to `[20, 30]`. Three facts carry almost every interview answer on this: **1. The starred name always binds a `list`.** Not a tuple, not a slice view, not the original container type. `*init, last = "chat"` gives `init == ['c', 'h', 'a']` and `last == 't'` — a list of one-character strings, not a string. `a, *b = (1, 2, 3)` gives `b == [2, 3]`, a list from a tuple. That surprises people who expect the right-hand type to be preserved, and it matters when the value flows into code that then compares it against a tuple or feeds it back to something type-sensitive. **2. The star may sit anywhere, but there can be only one.** All of `*init, last = xs`, `first, *rest = xs` and `head, *middle, tail = xs` are legal. Two stars in one target list is a compile-time error — `SyntaxError: multiple starred expressions in assignment` — because the split point would be ambiguous. The restriction is per target list, so a nested target list gets its own star: `(a, *b), c = [1, 2, 3], 4` binds `a` to `1`, `b` to `[2, 3]` and `c` to `4`. **3. The fixed targets impose a minimum, not an exact count.** With a star present the arity check changes from "exactly N" to "at least N", and the error message says so: `a, b, *c = [1]` raises `ValueError: not enough values to unpack (expected at least 2, got 1)`. There is no upper bound, and the starred target legitimately binds an empty list when the values run out exactly — `a, *mid, z = (1, 2)` gives `mid == []`. That empty-list case is the whole point: it is what lets you write one destructuring line for a variable-width record instead of a length check plus indexing. ### Where it shows up The form is an assignment *target*, so it works everywhere a target list works. Most usefully that includes `for` loops: `for kind, *tags in rows:` reads rows whose first field is fixed and whose tail varies, binding `tags` to a list of whatever remains, possibly empty. It also appears with a throwaway name — `first, *_ = values` — to say "I want the head and I am deliberately ignoring the rest". That last idiom deserves a caveat. Naming the starred target `_` does not make it free: the interpreter still builds the whole list and binds it, so the cost in time and memory is the same as `first, *rest`. If you truly want only the first item of a large or lazy source, take it directly from the iterator instead. ### The cost, and when it bites Because the starred target must know how many values are left over, unpacking has to run the right-hand side to exhaustion. For a list or tuple that is a cheap copy of the tail. For an iterator or generator it means full consumption — every element materialised into a list, every side effect in the producer executed, and no way to stop early. On an unbounded generator the assignment simply never returns. A pattern to avoid for the same reason is recursive head/tail processing (`head, *tail = seq` inside a function that recurses on `tail`): each level copies the remaining elements, turning a linear walk into quadratic work and, on long inputs, hitting the recursion limit as well. For sequences you already hold in memory, the starred form and manual index-plus-tail access do the same thing; the starred form wins on readability precisely because it states the shape — "one fixed field and a variable tail" — in the target list itself, where a reader sees it. ### Errors worth naming - Two stars in one target list: `SyntaxError` at compile time, before anything runs. - Fewer values than fixed targets: `ValueError` mentioning **at least** N. - A right-hand side that is not iterable at all: `TypeError: cannot unpack non-iterable int object` — the star does not change that. Nothing in this behaviour has changed through 3.14; the star in assignment targets has been stable since Python 3.0.
- If the right-hand side is a tuple, what type does the starred target bind?A `list`, always. `a, *b = (1, 2, 3)` gives `b == [2, 3]`, and `*init, last = "chat"` gives `init == ['c', 'h', 'a']`. The starred target never preserves the source container type, so code that later compares it against a tuple or passes it somewhere type-sensitive needs an explicit conversion.
- Why can a target list contain at most one starred target?Because two stars would make the split ambiguous — with `a, *b, *c = xs` there is no rule saying how many leftover values each star should claim. The compiler rejects it up front with `SyntaxError: multiple starred expressions in assignment`. A nested target list is a separate target list, so it may carry its own star.
- Does writing `first, *_ = values` avoid building the leftover list?No. The name `_` is an ordinary target; the interpreter still materialises every remaining value into a list and binds it. The cost in time and memory is identical to `first, *rest`. To take only the head of a large or lazy source, pull it from the iterator directly rather than unpacking.
saying these in an interview costs you the question
- Says the starred target keeps the right-hand side's type
- Thinks the star must be the last target
- Believes two starred targets are allowed if unambiguous
- Says a starred target must capture at least one value
- Claims starred unpacking is lazy over a generator
- Expects a wrong-count error to mention an exact count