The walrus operator (:=
) was introduced in Python 3.8 as part of PEP 572. It's officially called the "assignment expression" operator, but it earned its nickname because :=
resembles a walrus with tusks when viewed sideways. This operator allows you to assign values to variables as part of an expression, rather than as a separate statement.
The syntax is:
variable := expression
The walrus operator evaluates the expression, assigns the result to the variable, and then returns the result. This allows you to both assign and use a value in the same line of code.
One of the most common uses is to avoid computing the same value twice:
# Without walrus operator
result = some_expensive_function()
if result:
process(result)
# With walrus operator
if result := some_expensive_function():
process(result)
The walrus operator shines in list comprehensions and generator expressions:
# Calculate values once and use them twice
filtered_data = [y for x in data if (y := f(x)) > threshold]
# Process items in a file without reading the whole file into memory
chunks = [chunk for block in file if (chunk := process(block)) is not None]
It's particularly elegant in while loops where you need to both get and check a value:
# Without walrus operator
line = f.readline()
while line:
process(line)
line = f.readline()
# With walrus operator
while line := f.readline():
process(line)
When working with regex, you can capture and check matches in one step:
import re
# Without walrus operator
match = pattern.search(data)
if match:
process(match.group(1))
# With walrus operator
if match := pattern.search(data):
process(match.group(1))
The walrus operator doesn't create a new scope, which can be surprising:
if (x := 10) > 5:
print(x) # x is 10 here
print(x) # x is also 10 here, it "leaks" out of the if statement
The walrus operator has some syntactic restrictions:
# This works
(x := 1)
# These don't work
x := 1 # SyntaxError: cannot use assignment expressions with names
(x := 1) = 2 # SyntaxError: cannot assign to named expression
Using the walrus operator can make code more concise but potentially harder to read. Use it judiciously to maintain code clarity.
-
Use parentheses: Always wrap walrus expressions in parentheses unless they're already part of a larger expression.
# Good if (n := len(a)) > 10: print(f"List is too long ({n} elements)") # Also good (parentheses not needed in subexpressions) discount = 0.1 if (subtotal := sum(prices)) > 100 else 0
-
Single assignment per expression: Avoid multiple walrus operators in the same expression.
# Avoid this if (x := a + b) > 0 and (y := c + d) > 0: print(x, y)
-
Prioritize readability: If using the walrus operator makes your code harder to understand, use separate assignment statements instead.
def process_data(data):
if not (cleaned := clean_data(data)):
return "No valid data"
if not (analyzed := analyze_data(cleaned)):
return "Analysis failed"
if not (report := generate_report(analyzed)):
return "Report generation failed"
return report
def get_valid_input():
while not (user_input := input("Enter a positive number: ")).isdigit() or int(user_input) <= 0:
print("Invalid input. Please try again.")
return int(user_input)
import json
def process_json_file(filename):
try:
with open(filename, 'r') as f:
if not (data := json.load(f)):
return "Empty JSON file"
if not (user_data := data.get('users')):
return "No user data found"
return [user for user in user_data if (age := user.get('age', 0)) >= 18]
except json.JSONDecodeError:
return "Invalid JSON format"
The walrus operator is only available in Python 3.8 and later. If you need to support older Python versions, you'll need to use traditional assignment statements instead.
The walrus operator is a powerful addition to Python that can make your code more concise and efficient when used appropriately. By allowing assignment within expressions, it eliminates the need for redundant computations and can simplify common programming patterns. However, like any language feature, it should be used judiciously with readability and maintainability in mind.