Bucle for en una línea en Python [Un tutorial sencillo]

Rate this post

Python es potente: puedes condensar muchos algoritmos en una sola l√≠nea de c√≥digo. As√≠ que surge la pregunta natural: ¬Ņse puede escribir un bucle for en una sola l√≠nea de c√≥digo? Este art√≠culo explora con todo detalle esta cuesti√≥n fundamental.

¬ŅC√≥mo escribir un bucle for en una sola l√≠nea de c√≥digo Python?

Hay dos formas de escribir un bucle for de una línea:

  • M√©todo 1: Si el cuerpo del bucle consiste en una sola sentencia, simplemente escribe esta sentencia en la misma l√≠nea: for i in range(10): print(i). Esto imprime los 10 primeros n√ļmeros en la consola (del 0 al 9).
  • M√©todo 2: Si el objetivo del bucle es crear una lista, utiliza en su lugar la comprensi√≥n de listas: squares = [i**2 for i in range(10)]. El c√≥digo eleva al cuadrado los diez primeros n√ļmeros y los almacena en la lista squares.

Veamos ambas variantes con m√°s detalle.

Pero antes de seguir adelante, estoy encantado de presentarte mi nuevo libro Python One-Liners (enlace de Amazon).

Si te gustan las sentencias de l√≠nea √ļnica, te encantar√° este libro. Te ense√Īar√° todo lo que hay que saber sobre sentencias de l√≠nea √ļnica de c√≥digo Python. Pero tambi√©n es una introducci√≥n a la inform√°tica, la ciencia de datos, el aprendizaje autom√°tico y los algoritmos. ¬°El universo en una sola l√≠nea de Python!

El libro se publicó en 2020 con la editorial de libros de programación de categoría mundial NoStarch Press (San Francisco).

Enlace: https://nostarch.com/pythononeliners

Pero basta de promoci√≥n, vamos a sumergirnos en el primer m√©todo: el profano…

Método 1: bucle for de una línea

Escribir el bucle for en una sola línea de código es la forma más directa de realizar la tarea.

Digamos que queremos escribir el siguiente bucle for en una sola línea de código:

>>> for i in range(10):
    print(i)

    
0
1
2
3
4
5
6
7
8
9

Podemos conseguirlo fácilmente escribiendo el comando en una sola línea de código:

>>> for i in range(10): print(i)

0
1
2
3
4
5
6
7
8
9

Aunque esta respuesta parece sencilla, la pregunta interesante es: ¬Ņpodemos escribir un bucle for m√°s complejo que tenga un cuerpo de bucle m√°s largo en una sola l√≠nea?

Esto es mucho m√°s dif√≠cil. Aunque es posible condensar algoritmos complicados en una sola l√≠nea de c√≥digo, no existe una f√≥rmula general. Si te interesa comprimir algoritmos enteros en una sola l√≠nea de c√≥digo, consulta este art√≠culo con 10 sentencias de l√≠nea √ļnica de Python que caben en un solo tuit.

Supón que tienes el siguiente bucle más complejo:

for i in range(10):
    if i<5:
        j = i**2
    else:
        j = 0   
    print(j)

Esto genera la salida:

0
1
4
9
16
0
0
0
0
0

¬ŅPodemos comprimirlo en una sola l√≠nea? ¬°La respuesta es s√≠! Mira el siguiente fragmento de c√≥digo:

for i in range(10): print(i**2 if i<5 else 0)

Esto genera la misma salida que nuestro bucle for de varias l√≠neas. Resulta que podemos utilizar el operador ternario en Python que nos permite comprimir una sentencia if en una sola l√≠nea. Consulta este tutorial de nuestro blog si quieres saber m√°s sobre el apasionante operador ternario en Python. El operador ternario es muy intuitivo: basta con leerlo de izquierda a derecha para entender su significado. En el cuerpo del bucle print(i**2 if i<5 else 0) imprimimos el n√ļmero cuadrado i**2 si i es menor que 5, en caso contrario, imprimimos 0.

Vamos a explorar un truco alternativo de Python que es muy popular entre los maestros de Python:

Método 2: comprensión de lista

Aunque los novatos lo odian, los programadores experimentados de Python no pueden vivir sin esta impresionante función de Python.

Digamos que queremos crear una lista de n√ļmeros al cuadrado. La forma tradicional ser√≠a escribir algo parecido a esto

squares = []

for i in range(10):
    squares.append(i**2)
   
print(squares)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Creamos una lista vac√≠a squares y a√Īadimos sucesivamente n√ļmeros cuadrados empezando por 0**2 y terminando en 9**2. As√≠, el resultado es la lista [0, 1, 4, 9, 16, 25, 36, 49, 64, 81].

La comprensión de lista condensa esto en una sola línea de código, que además es legible, más eficiente y concisa.

print([i**2 for i in range(10)])

Esta línea consigue el mismo resultado con muchos menos bits.

Puedes encontrar un tutorial completo sobre la comprensión de listas en este recurso ilustrado del blog.

La comprensión de listas es una forma compacta de crear listas. La fórmula simple es [expresión + contexto].

  • Expresi√≥n: ¬ŅQu√© hacer con cada elemento de la lista?
  • Contexto: ¬ŅQu√© elementos de la lista hay que seleccionar? Consiste en un n√ļmero arbitrario de sentencias for e if.

La primera parte es la expresión. En el ejemplo anterior, era la expresión i**2. Utiliza en tu expresión cualquier variable que hayas definido en el contexto dentro de una sentencia de bucle.

La segunda parte es el contexto. En el ejemplo anterior, era la expresi√≥n for i in range(10). El contexto est√° formado por un n√ļmero arbitrario de cl√°usulas for e if. El √ļnico objetivo del contexto es definir (o restringir) la secuencia de elementos sobre los que queremos aplicar la expresi√≥n.

Método 3: bucle for de una línea en Python con if

También puedes modificar la sentencia de comprensión de lista restringiendo el contexto con otra sentencia if:

Problema: Digamos que queremos crear una lista de n√ļmeros al cuadrado, pero s√≥lo considerando los n√ļmeros pares e ignorando los impares.

Ejemplo: El c√≥digo de l√≠nea m√ļltiple ser√≠a el siguiente.

squares = []

for i in range(10):
    if i%2==0:
        squares.append(i**2)
   
print(squares)
# [0, 4, 16, 36, 64]

Creas una lista vac√≠a squares y a√Īades sucesivamente otro n√ļmero cuadrado empezando por 0**2 y terminando en 8**2, pero s√≥lo considerando los n√ļmeros pares 0, 2, 4, 6, 8. As√≠, el resultado es la lista [0, 4, 16, 36, 64].

De nuevo, puedes utilizar la comprensión de listas [i**2 for i in range(10) if i%2==0] con una cláusula if restrictiva (en negrita) en la parte del contexto para comprimir esto en una sola línea de código Python:

print([i**2 for i in range(10) if i%2==0])
# [0, 4, 16, 36, 64]

Esta línea consigue el mismo resultado con muchos menos bits.

Artículo relacionado: Bucle for de una línea en Python con if

Preguntas relacionadas

Vamos a profundizar en algunas preguntas relacionadas que pueden venir a tu mente.

¬ŅQu√© es una expresi√≥n generadora?

Una expresión generadora es una herramienta sencilla para generar iteradores. Si utilizas un bucle for, sueles iterar sobre un iterador. En este caso, una expresión generadora no crea explícitamente una lista en memoria. En su lugar, genera dinámicamente el siguiente elemento del iterable a medida que lo recorre. Hemos utilizado una expresión generadora en la sentencia print() anterior:

print(i**2 if i<5 else 0)

No hay corchetes alrededor de la expresión del generador, como sí ocurre con las comprensiones de lista.

¬ŅC√≥mo crear un bucle for anidado en una l√≠nea?

No podemos escribir un simple bucle for anidado en una línea de Python.

Digamos que quieres escribir un bucle for anidado como el siguiente en una línea de código Python:

for i in range(3):
    for j in range(3):
        print((i,j))

'''
(0, 0)
(0, 1)
(0, 2)
(1, 0)
(1, 1)
(1, 2)
(2, 0)
(2, 1)
(2, 2)
'''

Al intentar escribir esto en una sola línea de código, obtenemos un error de sintaxis:

for i in range(3): for j in range(3): print((i,j))
# Syntax Error

Sin embargo, podemos escribir una declaración de comprensiones de lista anidadas.

print([(i,j) for i in range(3) for j in range(3)])
# [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1),
# (1, 2), (2, 0), (2, 1), (2, 2)]

Esto sólo implica una parte de contexto algo más compleja for i in range(3) for j in range(3). Pero es manejable.

ūüí° Note: This article is a Spanish translation of our original article Python One Line For Loop (English).

A dónde ir desde aquí

Conocer peque√Īos trucos de Python de una sola l√≠nea, como la comprensi√≥n de listas y los bucles for de una sola l√≠nea, es vital para tu √©xito en el lenguaje Python. Todos los programadores expertos se los saben de memoria; al fin y al cabo, esto es lo que les hace ser muy productivos.

Si quieres aprender el lenguaje Python en profundidad, √ļnete a mi curso gratuito de Python por correo electr√≥nico. Est√° basado al 100% en chuletas y lecciones gratuitas de Python. Es divertido, f√°cil y puedes dejarlo cuando quieras.

Libro de sentencias de l√≠nea √ļnica de Python: ¬°Domina la l√≠nea √ļnica primero!

Los programadores de Python mejorar√°n sus destrezas inform√°ticas con estas √ļtiles sentencias de l√≠nea √ļnica.

Python One-Liners te ense√Īar√° a leer y escribir “one-liners”: Declaraciones concisas de funcionalidad √ļtil empaquetadas en una sola l√≠nea de c√≥digo. Aprender√°s a desempaquetar y comprender sistem√°ticamente cualquier l√≠nea de c√≥digo Python, y a escribir un Python elocuente y fuertemente comprimido como un experto.

Los cinco cap√≠tulos del libro cubren (1) consejos y trucos, (2) expresiones regulares, (3) aprendizaje autom√°tico, (4) temas b√°sicos de la ciencia de los datos y (5) algoritmos √ļtiles.

Las explicaciones detalladas de los one-liners introducen conceptos clave de la informática y potencian tu capacidad de programación y análisis. Aprenderás sobre funciones avanzadas de Python como comprensión de listas, rebanadas, funciones lambda, expresiones regulares, funciones map y reduce, y asignaciones de rebanadas.

También aprenderás a:

  • Aprovechar las estructuras de datos para resolver problemas del mundo real, como utilizar la indexaci√≥n booleana para encontrar ciudades con una contaminaci√≥n superior a la media
  • Utiliza los fundamentos de NumPy como array, shape, axis, type, broadcasting, advanced indexing, slicing, sorting, searching, aggregating, and statistics
  • Calcular estad√≠sticas b√°sicas de matrices de datos multidimensionales y los algoritmos K-Means para el aprendizaje no supervisado
  • Crea expresiones regulares m√°s avanzadas utilizando agrupaciones y grupos con nombre, b√ļsquedas negativas, caracteres escapados, espacios en blanco, conjuntos de caracteres (y conjuntos de caracteres negativos) y operadores codiciosos / no codiciosos
  • Comprender una amplia gama de temas de inform√°tica, como anagramas, pal√≠ndromos, superconjuntos, permutaciones, factoriales, n√ļmeros primos, n√ļmeros de Fibonacci, ofuscaci√≥n, b√ļsqueda y ordenaci√≥n algor√≠tmica

Al final del libro, sabr√°s c√≥mo Escribir Python de la forma m√°s refinadacrear piezas concisas y hermosas de “arte Python” en una sola l√≠nea.

¬°Consigue tu Python One-Liners en Amazon!