backend / python core / tricky questions / 11_walrus_operator_gotchas.md

Walrus operator (:=) gotchas

1 min read source

Walrus operator (:=) gotchas

The gotcha

The walrus operator (PEP 572, Python 3.8+) is an assignment expression — it returns the assigned value. It has lower precedence than most operators, requires parens in many contexts, and is forbidden at the top level of a statement.

Minimal repro

# Useful: avoid double-call
if (n := len(data)) > 10:
    print(f"too long: {n} items")

# Useful: read-and-test loop
while (chunk := f.read(1024)):
    process(chunk)

# Forbidden: top-level assignment expression
x := 5            # SyntaxError
(x := 5)          # works inside parens

# Precedence trap:
y = x := 5        # SyntaxError
y = (x := 5)      #

# Inside f-strings (3.8+ only with care):
print(f"{(n := 42)}")   # works in 3.12+, was a parse trap earlier

Why it happens

:= is intentionally awkward at the top level to discourage replacing =. Its precedence is below ,, so a, b := 1, 2 is parsed as a, (b := 1), 2 — a tuple, not an assignment.

It’s an expression (evaluates to the assigned value), unlike = which is a statement. That’s why you can use it inside if, while, comprehensions:

[y for x in data if (y := f(x)) is not None]

How to avoid

  • Use parens generously when in doubt — they disambiguate.
  • Don’t use := where = works fine. It’s for condense-the-test and assign-inside-comprehension cases.
  • For simple “assign and use” inside a chain of statements, regular = on its own line is clearer:
# Less clear:
if (data := fetch()) is not None and (n := len(data)) > 0: ...

# Clearer:
data = fetch()
if data is not None and len(data) > 0: ...

Interview angle

“Where would you use the walrus operator?” Good answer: regex matches (if (m := pattern.match(s)):), file-reading loops, expensive computations you want to test and reuse.