What is the Walrus Operator?
The Walrus Operator (:=
) is an assignment expression. It binds a value to a variable while returning that value, so you can use it immediately within the same expression.
if (n := len(data)) > 5:
print(f"Too long! ({n} items)")
Why “walrus”? Because :=
looks like a walrus face with tusks. 🦭
Without vs With Walrus
Without Walrus (two steps):
n = len(data)
if n > 5:
print(f"Too long! ({n} items)")
With Walrus (one step):
if (n := len(data)) > 5:
print(f"Too long! ({n} items)")
Benefit: Less repetition, no recomputing len(data)
.
Real‑World Use Cases
1) Read input until a sentinel
while (line := input(">>> ")) != "quit":
print("You typed:", line)
Keeps the code compact; no extra variable assignment line is needed before the loop.
2) Avoid duplicate expensive calls
if (user := get_current_user()) and user.is_admin:
grant_access(user)
You call get_current_user()
once, still reuse user
.
3) Regex matching, then reuse the match
import re
if (m := re.search(r"order-(\d+)", filename)):
order_id = int(m.group(1))
print("Found order:", order_id)
Cleaner than matching first, then writing a second if
.
4) Filter/map in one pass
results = [y for x in data if (y := transform(x)) is not None]
Transforms each x
and only keeps non‑None
results—without calling transform
twice.
5) Reading files line by line
with open("log.txt") as f:
while (chunk := f.read(4096)):
process(chunk)
Stops when an empty string is returned.
Subtle Gotchas (Readability First!)
1) Parentheses matter
# Good: assign len(data) to n, then compare n > 5
if (n := len(data)) > 5: ...
# Bad: assigns boolean result of (len(data) > 5) to n
if n := len(data) > 5: ...
Prefer the first form to avoid binding a bool to n
.
2) Don’t nest too much
Hard‑to‑read one‑liners are worse than two clear lines. If it harms clarity, don’t use walrus.
3) Comprehension scope
In comprehensions, the walrus‑assigned name is local to that comprehension and won’t leak outside—good for avoiding accidental name clashes.
4) Version check
Works in Python 3.8+. If you ship libraries, note this in your README.
Quick Patterns Cheat Sheet
If + reuse
if (val := compute()) is not None:
use(val)
While + fetch
while (item := queue.get()) is not None:
handle(item)
Comprehension + cache
pairs = [(name, l) for name in names if (l := len(name)) > 3]
Regex + branch
if (m := re.match(pat, s)): do_something(m)
When Not to Use It
- If it makes the line cryptic (especially for beginners on your team).
- If the expression becomes too long; split into two lines.
- If performance gain is negligible and readability drops.
Mini Exercises (copy → run → learn)
- Convert this to use a walrus (once), without changing behavior:
data = fetch_data()
if data and len(data) > 10:
print("Big list:", len(data))
One possible answer:
if (data := fetch_data()) and (n := len(data)) > 10:
print("Big list:", n)
- Turn this into a one‑line loop condition:
line = input()
while line != "":
print(line)
line = input()
One possible answer:
while (line := input()) != "":
print(line)
FAQ
Q: Is :=
the same as =
?
A: No. =
is a statement (assignment). :=
is an expression that assigns and returns the value, so you can use it inline.
Q: Does it improve performance?
A: It can, by avoiding repeated function calls. But its biggest win is cleaner code—don’t use it solely for micro‑optimizations.
Q: Is it safe in comprehensions?
A: Yes, it doesn’t leak variables outside the comprehension scope.
Q: Which Python versions support it?
A: Python 3.8+ (PEP 572).