What Does := Do in Python? The Walrus Operator
The Python walrus operator := assigns a value and returns it in one expression. Learn where it works, where it is illegal, and common patterns.
:= is the assignment expression, nicknamed the walrus operator. It assigns a value to a name and returns that value so you can use it in the same expression. It requires Python 3.8 or later.
# Without := you compute twice or need an extra line
text = "I'm cut in half"
mid = len(text) // 2
print(text[:mid], text[mid:])
# I'm cut in half
# With := the midpoint is assigned and reused on one line
text = "I'm cut in half"
print(text[:(mid := len(text) // 2)], text[mid:])
# I'm cut in half
print(mid)
# 7
The name sticks because := looks a little like a walrus on its side.
What problem does it solve?
Ordinary = is a statement. You cannot drop it inside an if, while or comprehension. Assignment expressions fill that gap when you need a value both for a test and for the body that follows:
# Assign then test on separate lines
match = pattern.search(line)
if match:
print(match.group(1))
# Assign and test in one expression
if match := pattern.search(line):
print(match.group(1))
The second form avoids calling pattern.search twice and avoids introducing match only to check it immediately.
Useful patterns
if and while
# Read until an empty line
while (line := input().strip()):
print(line.upper())
# Use a function result only when it is truthy
if (user := get_user(user_id)) is not None:
print(user.name)
Avoid repeating expensive work
# Without walrus: length computed twice
if len(items) > 10:
print(f"too many: {len(items)}")
# With walrus: length computed once
if (n := len(items)) > 10:
print(f"too many: {n}")
List and generator comprehensions
You can use := in the expression or in a filter condition:
def to_int(s):
try:
return int(s)
except ValueError:
return None
values = ["10", "x", "20", "y"]
# Keep only strings that convert to int, and store the int
nums = [n for s in values if (n := to_int(s)) is not None]
# [10, 20]
A related one-liner for splitting a string in half without repeating the midpoint calculation is covered in split a string in half in Python.
Assignment expression constraints
:= is not a full replacement for =. These rules matter in real code:
1. It is an expression, not a bare statement
At the top level of a statement, use ordinary assignment:
# Legal
x = 1
# Illegal as a statement
x := 1 # SyntaxError
Wrapping it in parentheses makes an expression statement that both assigns and returns the value—useful in the REPL:
>>> (x := 1)
1
2. Parentheses are often required
When := sits inside a larger expression, add parentheses so precedence is clear:
# Clear and valid
if (n := len(items)) > 10:
...
# Also common in slices and function arguments
print(text[:(mid := len(text) // 2)])
3. You cannot use it as a comprehension target
This is illegal:
# SyntaxError — cannot assign with := in the for target
[y for y := x in data]
Use a normal for target, then assign inside the expression or filter as shown earlier.
4. Scope follows normal Python rules
Names bound with := inside an if, while or comprehension live in the enclosing scope (the same scope as a normal assignment in that function or module). If an assignment expression is evaluated, the name is bound even when its value is falsy:
if (match := None):
print("found")
print(match) # None
The name can remain unbound when short-circuiting prevents the assignment expression from being evaluated:
if False and (value := get_value()):
print(value)
# value was never assigned
5. Prefer readability over density
If an assignment expression makes a line hard to parse, split it into two lines. The operator exists to remove duplication, not to pack logic into the fewest characters possible.
:= versus =
| Form | Role | Example |
|---|---|---|
= | Assignment statement | n = len(items) |
:= | Assignment expression (value is usable immediately) | if (n := len(items)) > 10: |
Use = when you only need to store a value. Use := when you need that value in the same expression that performs the assignment.
Quick reference
:=assigns and returns the assigned value (Python 3.8+).- Common places:
if,while, comprehensions, slices, function arguments. - Not a bare statement; often needs parentheses.
- Illegal as a
fortarget in comprehensions. - Bound names follow ordinary enclosing-scope rules.
For more examples and background on the name, see the companion post on the Python walrus operator.