In Post #60, we learned about sequence unpacking, an elegant way to assign items from a list or tuple to a set of variables, like a, b = [10, 20]
. We also learned its strict rule: the number of variables on the left must exactly match the number of items in the sequence on the right.
But what if you don’t know how long the list is? What if you want to pull off the first item and collect “all the rest” into another variable, regardless of how many items are left?
For this, Python gives us a powerful syntax enhancement called a starred expression. In this post, we’ll learn how to use the *
operator in assignments to flexibly handle unpacking iterables of any length.
The Problem: Unpacking a Mismatched List
Let’s quickly remember what happens when we try to unpack a list into the wrong number of variables.
# This will cause a ValueError!
# a, b = [1, 2, 3, 4]
Running this code crashes the program with ValueError: too many values to unpack
. Standard unpacking is rigid. It’s all or nothing.
The Solution: The Starred Expression (*var
)
A starred expression, marked with an asterisk *
before a variable name on the left side of an assignment, solves this problem. It tells Python:
“Collect any leftover items from the sequence and put them into this variable as a new list.”
You can only use one starred expression in a single assignment statement, but it can appear in any position.
Starred Expressions in Action
The best way to understand this is to see it in a few different scenarios.
Capturing the “Rest” of a List
This is the most common use case. You can grab the first element (the “head”) and assign all remaining elements (the “tail”) to a starred variable.
numbers = [1, 2, 3, 4, 5]
first, *rest = numbers
print(f"First item: {first}")
print(f"The rest of the items: {rest}")
The output will be:
First item: 1
The rest of the items: [2, 3, 4, 5]
Notice that rest
is now a list containing all the other elements.
Capturing the Middle
The starred expression doesn’t have to be at the end. You can use it to grab a variable number of items from the middle of a sequence.
numbers = [1, 2, 3, 4, 5, 6, 7]
first, *middle, last = numbers
print(f"First: {first}")
print(f"Middle: {middle}")
print(f"Last: {last}")
Python assigns the first item to first
, the last item to last
, and then collects everything in between into the middle
list.
First: 1
Middle: [2, 3, 4, 5, 6]
Last: 7
Capturing the Beginning
You can also place the starred expression at the beginning to grab all items except for the last few.
numbers = [1, 2, 3, 4, 5]
*beginning, second_to_last, last = numbers
print(f"Beginning: {beginning}")
print(f"Second to last: {second_to_last}")
print(f"Last: {last}")
The output is:
Beginning: [1, 2, 3]
Second to last: 4
Last: 5
What’s Next?
Starred expressions add a huge amount of flexibility to Python’s unpacking capabilities. They provide a clean and readable way to destructure sequences when you don’t know their exact length, allowing you to easily separate the “head” from the “tail” or peel off the ends of a collection.
We’ve now seen how the *
operator can be used on the left side of an assignment to collect values. This operator, along with its double-asterisk cousin **
, can also be used on the right side of an expression to “unpack” collections for a different purpose: merging. In Post #119, we will explore how to use *
and **
unpacking to easily merge lists and dictionaries.
Author

Experienced Cloud & DevOps Engineer with hands-on experience in AWS, GCP, Terraform, Ansible, ELK, Docker, Git, GitLab, Python, PowerShell, Shell, and theoretical knowledge on Azure, Kubernetes & Jenkins. In my free time, I write blogs on ckdbtech.com