The Star: Taking the Rest
Unpacking has one demand: the counts must match. That is fine when you know how long the list is and useless when you do not. A star in front of one of the names lifts the demand — that name takes everything left over, however much or little that is.
1One name for the first, one for the rest
# a star takes everything that is left over
first, *rest = [10, 20, 30, 40, 50]
print('first:', first)
print('rest: ', rest)
print('rest is a', type(rest))first: 10 rest: [20, 30, 40, 50] rest is a <class 'list'>
first, *rest = [...]Two names for five items — which would normally be a ValueError. The star says 'this one is not asking for exactly one item', so the counting rule applies to the other names only.
print('rest is a', type(rest))The starred name always ends up holding a LIST, even when the values came from a tuple or a string, and even when there is only one item in it. That is worth checking rather than assuming.
2Watch the star being served last
Pick first, *rest in the widget and step through it. The interesting frame is the last one, where rest is handed four items at once — and it is worth stepping the two broken cases again afterwards, to see what the star is rescuing you from.
Watch the items being dealt out — and watch what happens when the counts do not match.
Python checks nothing yet. It simply starts handing the items of [10, 20, 30] out to the names on the left, one each, in order.
3The star can go anywhere in the row of names
# the star can go anywhere in the row of names
*most, last = [10, 20, 30, 40, 50]
print('most:', most, 'last:', last)
first, *middle, last = [10, 20, 30, 40, 50]
print('first:', first, 'middle:', middle, 'last:', last)
a, *b = [7]
print('a:', a, 'b:', b)most: [10, 20, 30, 40] last: 50 first: 10 middle: [20, 30, 40] last: 50 a: 7 b: []
Read the last line twice. a took the only item, so there was nothing left for b — and b is an empty list, not an error and not None. “Everything that is left” is a perfectly good description of nothing at all.
*a, *b = [1, 2, 3] there is no way to say where the first name should stop, and Python refuses the line with SyntaxError: multiple starred expressions in assignment.4The ordinary names still have to be satisfied
The star relaxes the rule; it does not remove it. Every unstarred name still needs an item of its own, so a list that is too short is still an error:
# three ordinary names, two items
a, b, *c = [10, 20]
print(a, b, c)10 20 []
ValueError: not enough values to unpack (expected at least 2, got 1)
Note the wording: expected at least 2. Without a star it said expected 3; with one, Python knows only the minimum, and the message says so. Reading the message tells you whether a star was involved.
5Where it earns its keep
# the winner, and everybody else
scores = [98, 91, 88, 74, 65]
winner, *others = scores
print('Winner:', winner)
print('The other', len(others), 'scores:', others)
print('Best of the rest:', max(others))Winner: 98 The other 4 scores: [91, 88, 74, 65] Best of the rest: 91
This is the shape the star is for: one item is special and the remainder is a group — a winner and the field, a heading row and the data rows, a command and its arguments. Written with slices it would be scores[0] and scores[1:], which is perfectly fine and says less about your intention.
scores[0] and scores[1:]. Use whichever the question's wording suggests, and do not be surprised to meet the star in somebody else's code.6Recap
Ordinary names are served first, one item each, and the starred name gets whatever is left over.
Even from a tuple or a string, and even when it holds one item or none. An empty remainder is [], not None.
*most, last — first, *middle, last — first, *rest. Only one star per statement, or it would be ambiguous.
a, b, *c = [10] fails with 'expected at least 2', and that wording is the clue that a star was involved.
a, *b = [7]. What does b hold?
first, *middle, last = [10, 20, 30, 40, 50]. What is middle?
a, b, *c = [10] raises 'not enough values to unpack (expected at least 2, got 1)'. Why 'at least'?