El operador walrus := en Python 3.8: asignación dentro de expresiones

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.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP