What does `variable, _, _ = ...` mean in Python?

Learn what does variable, _, _ = ... mean in python? with practical examples, diagrams, and best practices. Covers python development techniques with visual explanations.

Understanding Python's variable, _, _ = ... Assignment

Hero image for What does `variable, _, _ = ...` mean in Python?

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

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

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