Often I used indexing and slicing to access items from Python lists and this can be error prone. We can prevent this by using less error-prone and cleaner way of catch-all unpacking.
Simple Example
fruits = ["apple", "banana", "strawberry", "orange", "kiwi"]
first, second, *rest = fruits
print(first, second, rest)
>>>
apple banana ['strawberry', 'orange', 'kiwi']
Advantages of using catch-all unpacking
- The code becomes shorter, easier to read, and less error-prone.
- “A starred expression may appear in any position”
first, *rest, last = fruits
print(first, rest, last)
>>>
apple ['banana', 'strawberry', 'orange'] kiwi
Notes
The catch-all unpacking must have at least one required part. Otherwise, a
SyntaxError
will be raised.*rest = fruits >>> File "<stdin>", line 1 SyntaxError: starred assignment target must be in a list or tuple
Multiple catch-all unpacking expressions in a single-level are not allowed
first, *middle, *second_middle, last = fruits >>> File "<stdin>", line 1 SyntaxError: two starred expressions in assignment
Unpacked values from starred expression always become
list
instances. If there are no leftover elements from the sequence being unpacked, the catch-all unpack will be an empty list.fruits = ["apple", "banana"] first, second, *rest = fruits print(first, second, rest) >>> apple banana []
It is possible to unpack values of iterators (ex: generator).
def generate_csv(): yield('Year', 'Title', 'Genre') ... it = generate_csv() header, *rows = it print('CSV Header:', header) print('Row count:', len(rows)) >>> CSV Header: ('Year', 'Title', 'Genre') Row Count: 200
As we noticed, we can get all the rows via
*rows
instead of converting iterators tolist
and accessing by indexing. Similarly, we can unpackheader
easily.- Important Note: A starred expression always becomes
list
so it may be risky to unpack an iterator because it may use up all memory on your machine and cause program to crash.
- Important Note: A starred expression always becomes