El operador walrus :=, introducido en Python 3.8 con la PEP 572, permite asignar un valor a una variable dentro de una expresión y usarlo inmediatamente en esa misma expresión. Resuelve el patrón repetido de "computar, comprobar, usar" en una sola línea.
El problema que resuelve
import re
# Sin walrus: la llamada se repite o necesitas una variable extra
linea = "ERROR: timeout en conexión"
match = re.search(r"ERROR: (.+)", linea)
if match:
print(match.group(1)) # timeout en conexión
# Con walrus: asigna y comprueba en una línea
if match := re.search(r"ERROR: (.+)", linea):
print(match.group(1))
Bucles while con streams
El patrón más común en la PEP 572 es leer chunks de un fichero o socket:
# Sin walrus: la lectura se repite o necesitas centinela
with open("datos.bin", "rb") as f:
bloque = f.read(4096)
while bloque:
procesar(bloque)
bloque = f.read(4096)
# Con walrus: limpio y sin duplicar la llamada
with open("datos.bin", "rb") as f:
while bloque := f.read(4096):
procesar(bloque)
List comprehensions con cálculo compartido
Cuando la expresión de filtro y la expresión de transformación comparten un cálculo costoso, el walrus evita hacerlo dos veces:
import math datos = [1.2, -0.5, 3.7, 0.1, -2.1, 4.9] # Sin walrus: math.sqrt se llama dos veces por elemento resultados = [math.sqrt(x) for x in datos if x >= 0 and math.sqrt(x) > 1.5] # Con walrus: math.sqrt se calcula una vez por elemento resultados = [raiz for x in datos if x >= 0 and (raiz := math.sqrt(x)) > 1.5] print(resultados) # [1.9235..., 2.2135...]
Expresiones regulares en series
import re
logs = [
"2026-06-01 ERROR timeout",
"2026-06-01 INFO usuario conectado",
"2026-06-02 ERROR disco lleno",
"2026-06-02 WARN memoria alta",
]
patron_error = re.compile(r"(d{4}-d{2}-d{2}) ERROR (.+)")
errores = [
(m.group(1), m.group(2))
for log in logs
if (m := patron_error.match(log))
]
print(errores)
# [('2026-06-01', 'timeout'), ('2026-06-02', 'disco lleno')]
Validación de entrada en bucle
def validar_edad(texto):
try:
n = int(texto)
return n if 0 < n < 150 else None
except ValueError:
return None
# Pedir hasta obtener entrada válida
while (edad := validar_edad(input("Introduce tu edad: "))) is None:
print("Edad no válida, inténtalo de nuevo")
print(f"Edad registrada: {edad}")
Cuándo no usarlo
# MAL: usar walrus donde una asignación normal es más clara x = 10 # esto no necesita walrus # MAL: anidar walrus hasta el punto de confundir resultado = [y := f(x), y**2, y**3] # difícil de seguir # BIEN: walrus solo cuando evita código repetido de forma obvia
El operador := no está pensado para reemplazar todas las asignaciones. Úsalo cuando la alternativa sea repetir una llamada costosa o añadir una variable temporal de un solo uso fuera de la expresión donde se necesita.
