Topic 19 of 64
Walrus Operator & Advanced Comprehensions
Overview
The walrus operator (:=, Python 3.8+) assigns and returns a value in a single expression. Combined with advanced comprehension patterns, it enables writing more efficient Python without sacrificing readability.
Syntax
python
# Walrus operator (:= ) — assign in expression
import re
# Without walrus: must call function twice
line = "Error: database connection failed at 14:23"
if re.match(r"Error:", line):
match = re.match(r"Error:", line) # called twice!
# With walrus: assign and test in one step
if m := re.match(r"Error: (.+)", line):
print(f"Error found: {m.group(1)}")
# In while loop — read until empty
while chunk := file.read(1024):
process(chunk)
# In comprehension — compute once
results = [y for x in data if (y := transform(x)) > 0]
# Advanced comprehension patterns
# Conditional expression
prices = [max(0, p) for p in raw_prices] # no negatives
# Flattening nested lists
flat = [item for sublist in nested for item in sublist]
# Dict from two lists
config = {k: v for k, v in zip(keys, values)}
# Invert a dict
inverted = {v: k for k, v in original.items()}Common Pitfalls
- Walrus operator in comprehensions can cause confusion — use it only when it genuinely simplifies code.
- The walrus variable leaks out of comprehension scope (unlike regular comprehension variables) — be aware of this side effect.
- Interview tip: [y for x in data if (y := f(x)) > 0] calls f(x) once per item, not twice — a real performance improvement over [f(x) for x in data if f(x) > 0].
Real-World Example
Processing a log file efficiently with walrus operator:
example
python
import re
from collections import defaultdict
ERROR_PATTERN = re.compile(r"(\d{4}-\d{2}-\d{2}) ERROR (.+?)(?:\[(.+?)\])?$")
WARNING_PATTERN = re.compile(r"(\d{4}-\d{2}-\d{2}) WARN (.+)")
def parse_logs(log_lines: list[str]) -> dict:
errors_by_date = defaultdict(list)
warnings = []
for line in log_lines:
# Walrus: match and extract in one step
if m := ERROR_PATTERN.match(line):
date, message, source = m.group(1), m.group(2), m.group(3)
errors_by_date[date].append({
"message": message,
"source": source or "unknown"
})
elif m := WARNING_PATTERN.match(line):
warnings.append({"date": m.group(1), "message": m.group(2)})
return {
"errors": dict(errors_by_date),
"warnings": warnings,
"summary": {
date: len(errs)
for date, errs in errors_by_date.items()
}
}