Python 3.8: Walrus Operator := Controversy

python dev

Python 3.8 introduces the walrus operator (:=). It’s officially called “assignment expressions.” The debates were so heated that Guido van Rossum stepped down as BDFL.

Was it worth the drama?

What is the Walrus Operator?

It assigns a value to a variable as part of an expression:

# Before: Assign then use
data = get_data()
if data:
    process(data)

# After: Assign within expression
if (data := get_data()):
    process(data)

The variable data is assigned AND used in the same line.

Why “Walrus”?

:= looks like a walrus on its side. Eyes and tusks.

Practical Use Cases

While Loops

# Before
line = f.readline()
while line:
    process(line)
    line = f.readline()

# After
while (line := f.readline()):
    process(line)

No more duplicated readline.

List Comprehensions with Side Effects

# Before: Call expensive function twice or use temporary list
results = []
for x in data:
    y = expensive_computation(x)
    if y > threshold:
        results.append(y)

# After
results = [y for x in data if (y := expensive_computation(x)) > threshold]

Compute once, filter and use.

Regex Matching

# Before
match = pattern.match(line)
if match:
    print(match.group(1))

# After
if (match := pattern.match(line)):
    print(match.group(1))

Simplifying Conditionals

# Before
results = do_query()
if len(results) > 10:
    print(f"Found {len(results)} results")

# After
if (n := len(results := do_query())) > 10:
    print(f"Found {n} results")

Though this might be too clever.

The Controversy

Why People Objected

  1. Readability: Python values explicitness. := is subtle.
  2. Abuse potential: Encourages clever one-liners
  3. Inconsistency: Different from regular assignment
  4. Debugging: Order of operations can be confusing

Why Guido Stepped Down

The PEP 572 debates were intense. Guido approved the PEP and faced significant pushback. He wrote:

“I’m tired, and need a break.”

He stepped down as BDFL (Benevolent Dictator For Life) after three decades.

Python now uses a Steering Council for governance.

Style Guidelines

Do Use When

Avoiding repeated expensive calls:

if (match := pattern.search(data)) is not None:
    return match.group(0)

Reducing loop setup:

while (block := file.read(256)):
    process(block)

Capturing intermediate values:

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

Don’t Use When

It harms readability:

# Too clever
if (n := len(a := get_list())) > (m := len(b := get_other())):
    ...

The normal form is clearer:

# Just use this
data = get_data()
if data:
    process(data)

In simple statements:

# Pointless
(x := 10)  # Just write: x = 10

PEP 572 Restrictions

The walrus operator has limitations:

# Can't use at top level (use = instead)
(x := 10)  # Requires parentheses

# Can't use in comprehension iteration target
[x := i for i in range(10)]  # SyntaxError

# Can't use in f-string expressions without parentheses
f"{x:=10}"  # This is formatting, not walrus
f"{(x := 10)}"  # This works

Migration

Python 3.8+ only. Check:

import sys
if sys.version_info >= (3, 8):
    # Can use walrus

Or just set minimum Python version in your project.

Other Python 3.8 Features

Don’t miss these:

Positional-Only Parameters

def greet(name, /, greeting="Hello"):
    return f"{greeting}, {name}"

greet("Alice")  # OK
greet(name="Alice")  # TypeError

f-string = for debugging

x = 10
print(f"{x=}")  # Output: x=10

typing.Final

from typing import Final

MAX_SIZE: Final = 100

Should You Use It?

Yes, sparingly.

The walrus operator is a tool. Like all tools, it can be misused. Good candidates:

Bad candidates:

Final Thoughts

The walrus operator is a modest addition that caused immodest drama. It fills a real gap but isn’t revolutionary.

Use it where it genuinely simplifies code. Avoid it when you’re showing off. Python’s readability culture remains more important than any single operator.


Simple is better than complex. Unless you need a walrus.

All posts