What does `variable, _, _ = ...` mean in Python?
variable, _, _ = ...
mean in python? with practical examples, diagrams, and best practices. Covers python development techniques with visual explanations.Categories:
Understanding Python's variable, _, _ = ...
Assignment

Explore the meaning and practical applications of using underscores in Python's multiple assignment syntax, particularly for ignoring unwanted values.
In Python, multiple assignment is a powerful feature that allows you to assign values to several variables in a single line. A common pattern you might encounter is variable, _, _ = ...
. This syntax is not a special operator, but rather a clever use of Python's assignment capabilities combined with a conventional identifier: the underscore (_
). This article will demystify this pattern, explain its purpose, and show you how to use it effectively in your code.
The Basics of Multiple Assignment
Before diving into the role of the underscore, let's briefly review how multiple assignment works in Python. When you have an iterable (like a tuple, list, or string) on the right-hand side of an assignment operator, and a corresponding number of variables on the left-hand side, Python unpacks the iterable and assigns each element to its respective variable.
data = ("Alice", 30, "New York")
name, age, city = data
print(f"Name: {name}, Age: {age}, City: {city}")
# Output: Name: Alice, Age: 30, City: New York
Basic multiple assignment in Python
The Role of the Underscore (_
)
The underscore (_
) in Python has a few conventional uses, and one of its most common is as a placeholder for values you intend to ignore. When you see variable, _, _ = ...
, it means that you are interested in the value assigned to variable
, but you explicitly do not care about the second and third values returned by the expression on the right-hand side. These values are still unpacked, but they are assigned to _
, signaling to other developers (and often to yourself) that they are intentionally discarded.
flowchart TD A[Function Returns Multiple Values] --> B{Unpack into Variables} B --> C["variable (Value of Interest)"] B --> D["'_' (Ignored Value 1)"] B --> E["'_' (Ignored Value 2)"] C --> F[Use 'variable'] D -.-> G[Discarded] E -.-> G[Discarded]
Flow of multiple assignment with ignored values using underscores
def get_user_info():
# Imagine this function returns name, age, and email
return "Bob", 25, "bob@example.com"
# We only care about the name
user_name, _, _ = get_user_info()
print(f"User's name: {user_name}")
# Output: User's name: Bob
# The values assigned to '_' are still technically there, but conventionally ignored
# print(_) # This would print the last value assigned to _ ('bob@example.com')
Using underscores to ignore specific return values
_
is a valid variable name, it's conventionally used for throwaway values. Be mindful that if you use multiple _
in a single assignment, they all refer to the same variable _
, and its value will be the last value assigned to it. This is generally not an issue for ignoring values, as you typically don't access _
afterwards.Practical Use Cases
This pattern is incredibly useful in various scenarios where a function or operation returns more data than you immediately need. Some common examples include:
1. Iterating with enumerate()
my_list = ['apple', 'banana', 'cherry']
# If you only need the item, not the index
for _, item in enumerate(my_list):
print(f"Item: {item}")
# Output:
# Item: apple
# Item: banana
# Item: cherry
Ignoring the index when iterating with enumerate()
2. Swapping Variables (less common with _
but illustrates the principle)
a = 10
b = 20
a, b = b, a # Pythonic way to swap
# While not typically using '_', this shows multiple assignment
# If a function returned (new_a, new_b) and you only needed new_a:
# new_a, _ = some_function_returning_two_values()
print(f"a: {a}, b: {b}")
# Output: a: 20, b: 10
Variable swapping using multiple assignment
3. Function Returns Multiple Values
def process_data(data):
# Returns processed_data, status_code, and error_message
if data:
return data.upper(), 200, None
else:
return None, 400, "Input data is empty"
# We only care about the processed data and the status code
processed_result, status, _ = process_data("hello world")
print(f"Processed: {processed_result}, Status: {status}")
# Output: Processed: HELLO WORLD, Status: 200
processed_result, status, _ = process_data(None)
print(f"Processed: {processed_result}, Status: {status}")
# Output: Processed: None, Status: 400
Ignoring error messages from a function's return
*
with _
, like first, *_, last = my_list
. This collects all intermediate values into a list assigned to _
, which is then ignored.my_long_list = [1, 2, 3, 4, 5, 6, 7]
# Get the first and last elements, ignore everything in between
first, *_, last = my_long_list
print(f"First: {first}, Last: {last}")
# Output: First: 1, Last: 7
Using starred assignment with _
to ignore multiple values