The Walrus Operator :=
Assign inside an expression to avoid repeating work — used well, it reads beautifully.
The walrus operator := (named for its := eyes-and-tusks look) assigns a value and returns it, all inside a larger expression. It was added in Python 3.8 to kill a common repetition.
The problem it solves
You often compute something, test it, then use it again — writing the computation twice or adding an extra line:
# Without walrus: value computed, then re-used
data = get_data()
if data:
process(data)
# With walrus: compute, test, and bind in one breath
if (data := get_data()):
process(data)Where it earns its keep
- In
whileloops reading until a sentinel:while (line := f.readline()):. - Inside comprehensions to avoid calling an expensive function twice.
- In
if/elifchains where you need the tested value in the body.
Use it sparingly. When it removes a genuine repetition it is a joy; when it just crams two ideas onto one line, a plain assignment is kinder to the next reader.
Example
import statistics
readings = [12, 40, 7, 55, 33, 9, 61, 4]
# 1) Filter AND reuse the computed value — call the expensive fn once
def normalise(x):
# pretend this is costly
return round(x / 61, 3)
strong = [norm for x in readings if (norm := normalise(x)) > 0.5]
print('strong signals :', strong)
# 2) A processing loop that stops at the first out-of-range value
stream = iter([3, 8, 5, 99, 2])
total = 0
while (value := next(stream, None)) is not None and value < 50:
total += value
print('total before spike :', total) # 3 + 8 + 5 = 16
# 3) Compute once, report in the same breath
if (n := len(readings)) > 5:
print(f'{n} readings, mean = {statistics.mean(readings):.1f}')
# Output:
# strong signals : [0.902, 1.0]
# total before spike : 16
# 8 readings, mean = 27.6When to use it
- A while loop reads and processes chunks from a file until the read returns an empty bytes object.
- A list comprehension uses := to filter by a computed value and include that value in the output list.
- A regex search assigns the match object with := inside an if statement to avoid calling re.search twice.
More examples
Walrus in a while loop
Assigns the read() result to 'chunk' and tests it in the same expression, replacing the read-twice pattern.
import io
buf = io.BytesIO(b'hello world')
while chunk := buf.read(5):
print(chunk)
# Output:
# b'hello'
# b' worl'
# b'd'Walrus in a list comprehension
Computes y := x*2 once inside the comprehension, uses it in the filter and includes it in the output.
data = [1, 4, 9, 16, 25]
results = [y for x in data if (y := x * 2) > 10]
print(results) # [18, 32, 50]Walrus with regex match
Uses := to assign the match object in the if-condition, avoiding a separate assignment line.
import re
lines = ['Order #1042: shipped', 'Inquiry: no order', 'Order #2201: pending']
for line in lines:
if m := re.search(r'#(\d+)', line):
print('Order number:', m.group(1))
# Output:
# Order number: 1042
# Order number: 2201
Discussion