The Walrus Operator

Reviewed & published by Brayan K

The walrus operator := is an assignment expression that assigns a value to a variable and returns that value at the same time, letting you capture a result inside a larger expression.

Part of the free Python course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

Added in Python 3.8, it trims duplication in while loops, if conditions, and comprehensions — computing a value once and reusing it on the very same line.

What You'll Learn in This Lesson

1 Assign and Use in One Step

A plain = is a statement and produces no value. The walrus := is an expression: it assigns and hands back the value, so it can live inside a bigger expression:

# Without the walrus: compute, then test
data = [1, 2, 3, 4, 5]
n = len(data)
if n > 3:
    print(f"List is long ({n} items)")   # List is long (5 items)

# With the walrus: capture n right in the condition
if (n := len(data)) > 3:
    print(f"List is long ({n} items)")   # List is long (5 items)

# The walrus returns the value it just assigned
print((x := 10))      # 10  -> x is now 10
print(x + 5)          # 15

🔁 Cleaner while Loops

The walrus removes the awkward "read once before the loop, then read again at the bottom" pattern. Read and test in the condition itself:

# Simulate reading lines until a blank one
lines = iter(["alpha", "beta", "", "gamma"])

# The clunky pattern: duplicate the read
# line = next(lines)
# while line != "":
#     print(line)
#     line = next(lines)   # <- repeated!

# With the walrus: one read, no duplication
while (line := next(lines)) != "":
    print("Got:", line)

print("Stopped at blank line")

# Expected:
# Got: alpha
# Got: beta
# Stopped at blank line

Each loop iteration calls next(lines), stores the result in line, and tests it — all in one place. No more forgetting to repeat the read at the bottom of the loop.

# Process chunks until an empty one appears
chunks = iter(["data1", "data2", "data3", "", "ignored"])
total = 0

while (chunk := next(chunks)) != "":
    total += len(chunk)
    print("Processing:", chunk)

print("Total chars:", total)

# ✅ Expected output:
# Processing: data1
# Processing: data2
# Processing: data3
# Total chars: 15

2 Reuse a Value in Comprehensions & Conditions

When an expensive or repeated computation appears in a comprehension's filter and its output, the walrus computes it once:

def process(n):
    return n * n - 1      # pretend this is expensive

nums = [1, 2, 3, 4, 5]

# Without walrus: process(n) runs TWICE per item
result = [process(n) for n in nums if process(n) > 5]

# With walrus: compute once, reuse the result
result = [y for n in nums if (y := process(n)) > 5]
print(result)             # [8, 15, 24]

# Walrus in an if, reusing the match
import re
text = "order: 42"
if (m := re.search(r"\d+", text)):
    print("Found number:", m.group())   # Found number: 42
# Capture a value once, reuse it in the same comprehension
words = ["hi", "hello", "hey", "greetings", "yo"]

# Keep words longer than 3 chars, and report their length
result = [(w, n) for w in words if (n := len(w)) > 3]
print(result)            # [('hello', 5), ('greetings', 9)]

# Walrus inside an if, reusing the computed total
basket = [4, 9, 2, 7]
if (total := sum(basket)) > 20:
    print(f"Over budget by {total - 20}")   # Over budget by 2
else:
    print(f"Under budget: {total}")

# ✅ Expected output:
# [('hello', 5), ('greetings', 9)]
# Over budget by 2

⚖️ Readability Limits

The walrus is a scalpel, not a hammer. It helps when it removes duplication; it hurts when it crams unrelated work into one line:

# 👍 GOOD: removes a real duplicate computation
if (size := len(payload)) > 1024:
    print(f"Too big: {size} bytes")

# 👎 BAD: hard to read, no real benefit
print(y := (x := 5) + (z := 3))   # too clever, avoid

# 👍 Often clearer as two plain lines:
x = 5
z = 3
y = x + z
print(y)

Ask: "does := remove duplication or save a meaningful line?" If yes, use it. If it just looks clever, prefer two ordinary lines — clarity wins.

🎯 Your Turn: Fill in the Blanks

Replace each ___ with a walrus assignment so the output matches.

# 🎯 YOUR TURN: replace each ___ with a walrus (name := value)
data = [3, 8, 1, 9, 4]

# 1. Capture the max in the condition and reuse it
if (___) > 8:                       # hint: biggest := max(data)
    print(f"Peak is {biggest}")     # Peak is 9

# 2. In a comprehension, square each item once and keep squares > 10
squares = [s for n in data if (___) > 10]   # hint: s := n * n
print(squares)                      # [64, 81, 16]

# Expected output:
# Peak is 9
# [64, 81, 16]
if (biggest := max(data)) > 8:
    print(f"Peak is {biggest}")

squares = [s for n in data if (s := n * n) > 10]
print(squares)   # [64, 81, 16]

Common Errors & How to Fix Them

❌ Using a plain = in a condition

if (n = len(data)) > 3:   # SyntaxError - = is not an expression

✅ Use the walrus inside conditions: if (n := len(data)) > 3:. Plain = only works as its own statement.

total = sum(x := 5, ...)   # ambiguous / SyntaxError in many spots

✅ Wrap the walrus: (x := 5). The parentheses resolve precedence and make the assignment clear.

❌ Reaching for it on Python 3.7 or older

# SyntaxError on Python < 3.8

✅ The walrus needs Python 3.8+. On older versions, assign on a separate line first.

🎯 Mini Challenge: Running Threshold

Use the walrus to find the first running total that crosses a threshold.

# Mini Challenge: stop when the running total exceeds 15
amounts = [4, 3, 6, 5, 8]
running = 0

for a in amounts:
    if (running := running + a) > 15:
        print(f"Crossed 15 at +{a}, total={running}")
        break
    print(f"Added {a}, total={running}")

# Bonus: keep only readings whose doubled value exceeds 10, once
readings = [3, 7, 2, 9]
big = [d for r in readings if (d := r * 2) > 10]
print("Doubled & big:", big)

# Expected output:
# Added 4, total=4
# Added 3, total=7
# Added 6, total=13
# Crossed 15 at +5, total=18
# Doubled & big: [14, 18]

📚 Keep Learning

Go deeper with the official Python documentation:

Frequently Asked Questions

Lesson complete — the walrus is tamed!

You can assign and use a value in one expression with :=, write cleaner while loops, reuse computations in comprehensions and conditions, and judge when it helps versus when it just looks clever.

Practice quiz

What does the walrus operator := do?

  • It compares two values for equality
  • It only works inside function definitions
  • It assigns a value to a variable AND returns that value as an expression
  • It deletes a variable after use

Answer: It assigns a value to a variable AND returns that value as an expression. The walrus := is an assignment expression: it assigns and evaluates to the assigned value, so it can live inside conditions and comprehensions.

In which Python version was the walrus operator introduced?

  • Python 3.8
  • Python 3.6
  • Python 3.7
  • Python 3.10

Answer: Python 3.8. PEP 572 added the walrus operator in Python 3.8; using it on 3.7 or older raises a SyntaxError.

Why does a plain = fail inside an if condition like 'if (n = len(data)) > 3:'?

  • Because = is too slow there
  • Because len() cannot be used in conditions
  • Because n is a reserved word
  • Because plain = is a statement, not an expression, so it produces no value to test

Answer: Because plain = is a statement, not an expression, so it produces no value to test. Plain = is a statement and yields no value, so it is a SyntaxError inside a condition. The walrus := is an expression and works.

What is the value of x after this runs: print((x := 10))?

  • None
  • 10
  • True
  • It raises an error

Answer: 10. (x := 10) assigns 10 to x and returns 10, so 10 is printed and x is now 10.

What does this print? squares = [s for n in [1,2,3] if (s := n*n) > 3]; print(squares)

  • [4, 9]
  • [1, 4, 9]
  • [2, 3]
  • [9]

Answer: [4, 9]. n*n is computed once per item and bound to s; only squares > 3 are kept, giving [4, 9] (4 from 2, 9 from 3).

A key benefit of the walrus inside a while condition is that it:

  • Makes the loop run faster than any other form
  • Automatically stops infinite loops
  • Lets you read and test a value in one place, removing a duplicated read
  • Converts the loop into a comprehension

Answer: Lets you read and test a value in one place, removing a duplicated read. while (line := next(lines)) != '': reads and tests in the condition, eliminating the clunky 'read before, read again at the bottom' duplication.

Why is wrapping the walrus in parentheses, like (n := len(data)), recommended?

  • Parentheses make it run at compile time
  • It resolves precedence and is always syntactically safe and clear
  • Python deletes the variable without them
  • It is required to import the operator

Answer: It resolves precedence and is always syntactically safe and clear. Parentheses make precedence explicit and keep the assignment valid and obvious; bare := is sometimes rejected or read oddly.

In a comprehension, what is the walrus's main advantage when a function appears in both the filter and the output?

  • It sorts the result automatically
  • It makes the comprehension lazy
  • It removes the need for a for clause
  • It computes the function once per item instead of twice

Answer: It computes the function once per item instead of twice. [y for n in nums if (y := f(n)) > 5] calls f(n) once per item and reuses y, instead of calling f(n) in both the filter and the output.

When is the walrus operator a POOR choice?

  • When it removes a genuine duplicated computation
  • When it crams unrelated assignments into one line just to look clever
  • When used in a while condition
  • When wrapped in parentheses

Answer: When it crams unrelated assignments into one line just to look clever. The walrus shines at removing real duplication; using it to golf unrelated work into one dense line hurts readability.

After 'if (biggest := max([3,8,1,9,4])) > 8:', what value does biggest hold inside the block?

  • 8
  • True
  • 9
  • 4

Answer: 9. max([3,8,1,9,4]) is 9, which is assigned to biggest and is greater than 8, so the block runs with biggest == 9.

Continue this course

Frequently asked questions

What is the walrus operator?

The walrus operator := is an assignment expression, added in Python 3.8. It assigns a value to a variable AND returns that value at the same time, so you can capture a result right inside a larger expression — like an if, while, or comprehension — instead of needing a separate assignment line first.

Why is it called the walrus operator?

Because := looks like the eyes and tusks of a walrus tilted on its side. The official name is 'assignment expression', but the nickname stuck. It was introduced by PEP 572 and is one of the few operators with a memorable face.

How is := different from =?

Plain = is a statement: it assigns but produces no value, so you can't put it inside an if or while condition. The walrus := is an expression: it assigns AND evaluates to the assigned value, so it can live inside conditions, comprehensions, and function arguments where a bare = is a syntax error.

When should I avoid the walrus operator?

Avoid it when it hurts readability. Cramming an assignment into an already-complex line, or using it just to save one short line, makes code harder to scan. It shines when it removes genuine duplication — computing a value once and reusing it in the same condition — not as a golfing tool to shorten everything.