Yeda AI Tips · #123

English

¿Dos ifs en una comprensión? Dale un nombre de función

Si tu list comprehension necesita un segundo if, necesita un nombre de función. Una comprensión es una gran herramienta para una transformación y, como máximo, un filtro simple. En el momento en que apilas dos condiciones — o una condición más un bucle anidado — en una sola línea entre corchetes, escribiste algo que el próximo lector tiene que descomprimir mentalmente. Mejor ponle nombre.

Por qué una línea deja de ser legible

Una comprensión empaqueta tres cosas en una expresión: qué produces, de dónde viene y qué conservas. Con un for y un if, el ojo la procesa en una sola pasada. Agrega un segundo if, otra cláusula for o un ternario dentro de la expresión de salida, y el lector ahora malabarea 4–5 piezas móviles sin ningún paso intermedio con nombre.

Las guías de estilo son directas al respecto. La guía de estilo de Python de Google (sección 2.7) permite comprensiones pero establece que "no se permiten múltiples cláusulas for ni expresiones de filtro — optimiza para legibilidad, no para concisión". El principio central de PEP 8 es el mismo: la legibilidad cuenta, y los one-liners comprimidos e ingeniosos se desaconsejan porque el código se lee mucho más de lo que se escribe. Incluso el tutorial oficial de Python, justo después de mostrar una comprensión anidada, te dice que "en el mundo real deberías preferir funciones integradas a sentencias de flujo complejas".

La solución: expandir en una función generadora con nombre

Toma una línea como esta:

active_admins = [u.email for u in users
                 if u.is_active if u.role == "admin"]

Expándela en una función generadora cuyo nombre declare la intención:

def active_admin_emails(users):
    for user in users:
        if not user.is_active:
            continue
        if user.role != "admin":
            continue
        yield user.email

active_admins = list(active_admin_emails(users))

Acaban de pasar tres cosas:

  1. La lógica recibió un nombre. active_admin_emails documenta la intención en cada punto de llamada — sin necesidad de comentarios.
  2. Se volvió testeable. Puedes probar la función directamente con tres fixtures mínimos: un admin inactivo, un no-admin activo, un admin activo. La comprensión inline solo podía probarse a través de lo que la rodeaba.
  3. Siguió siendo perezosa. Una función generadora produce elementos de a uno, igual que la prima de la comprensión, la generator expression — así que no pierdes nada en memoria. Llama a list() solo cuando de verdad necesites una lista.

Reglas prácticas

FormaVeredicto
Un for, sin ifComprensión — ideal
Un for, un if simpleComprensión — todavía bien
Dos cláusulas if (o if + ternario)Función generadora con nombre
Dos cláusulas for (bucles anidados)Función con nombre o bucles explícitos
Cualquier comprensión que tuviste que cortar en dos líneasFunción con nombre

El disparador es mecánico a propósito: "segundo if → nombre de función" es una regla que nunca hay que discutir en el code review.

Por qué importa más con un agente de código

Los agentes de código imitan el código que los rodea. Si tu base de código está llena de comprensiones densas de múltiples cláusulas, el agente aprende que anidar lógica en una línea es el estilo de la casa — y va a generar con gusto monstruos de cuatro cláusulas que después tienes que revisar carácter por carácter. Siembra el repositorio con funciones generadoras con nombre y el agente copia ese patrón: unidades pequeñas, con nombre, testeables individualmente, que además puede modificar con seguridad, porque cada condición vive en su propia línea con su propio diff.

Notas para usuarios avanzados

Recursos

Mira el reel y luego profundiza. Yeda AI Tips es una serie de videos cortos sobre programación asistida por IA — un consejo concreto por minuto. Read in English

Habla con nosotros · Lee el blog