Advertisement
  1. Code
  2. Python

Comprensiones de Listas en Python

Scroll to top
Read Time: 8 min

() translation by (you can also view the original English article)

Las comprensiones de listas te proveen una forma de escribir bucles for más concisamente. Pueden ser útiles cuando quieres crear nuevas listas a partir de listas existentes o iterables. Por ejemplo, puedes usar comprensiones de listas para crear una lista de cuadrados a partir de una lista de números. Similarmente, podrían también usar algunas condiciones en una lista de números así la nueva lista que crees es un subconjunto de la lista original.

Mantén en mente que no puedes escribir cada bucle for como una comprensión de lista. Ona cosa más: el nombre "comprensión de lista" puede ser un poco confuso porque parece sugerir que las comprensiones solo son para trabajar con listas. En realidad, la palabra "lista" en comprensiones de lista, es usada para indicar que puedes hacer iterar sobre cualquier iterable en Python y el producto final sería una lista.

Bucles y Comprensiones de Listas

Las comprensiones de listas básicas que no usan ninguna condición tienen la siguiente forma:

1
[<the_expression> for <the_element> in <the_iterable>]

Vamos a comenzar escribiendo un muy básico bucle for para listar los primeros 15 multiples de 5. Primero, necesitas crear una lista vacía. Entonces, tienes que iterar sobre un rango de números y multiplicarlos por 5. La nueva secuencia de números que obtienes consistirán de multiples de 5.

1
multiples = []
2
3
for n in range(1,16):
4
    multiples.append(n*5)
5
    
6
print(multiples)
7
# [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75]

El siguiente loop for tiene básicamente la siguiente estructura.

1
for <the_element> in <the_iterable>:
2
    <the_expression>

Si lo comparas con la forma de comprensión de lista que leíste anteriormente, puedes ver que <the_element> es n, <the_iterable> es range(1, 16) y <the_expression> es n*5. Poniendo estos valores en la comprensión de lista nos dará el siguiente resultado:

1
multiples = [n*5 for n in range(1,15)]
2
3
multiples
4
# [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70]

Similarmente, puedes también obtener una lista con el cubo de los números dados como esto:

1
cubes = [n**3 for n in range(1,16)]
2
3
print(cubes)
4
#[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000, 1331, 1728, 2197, 2744, 3375]

Condiciones en Comprensiones de Listas

Puedes también usar un condicional if para filtrar ciertos valores de la lista final. En este caso, la comprensión de lista toma la siguiente forma:

1
[<the_expression> for <the_element> in <the_iterable> if <the_condition>]

Un ejemplo básico para este tipo de comprensión sería conseguir todos los números pares en un rango dado. Un bucle for para hacer esta tarea se vería como esto:

1
evens = []
2
3
for n in range(1,21):
4
    if n%2 == 0:
5
        evens.append(n)
6
        
7
print(evens)
8
# [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

Lo mismo podría conseguirse usando la siguiente comprensión de lista:

1
evens = [n for n in range(1,21) if n%2 == 0]
2
3
print(evens)
4
# [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

Un ejemplo mas complejo de usar comprensiones de lista sería agregando expresiones condicionales .. if .. else .. dentro de ellas.

En este caso, el orden en el cual pones los enunciados dentro de la comprensión de lista será diferente de condicionales if usuales. Cuando solo tienes una condición if, la condición va al final de la comprensión. Sin embargo, en el caso de una expresión .. if .. else .. las posiciones para el bucle for y la expresión condicional son intercambiadas. El nuevo orden es:

1
[<the_expression> if <the_condition> else <other_expression> for <the_element> in <the_iterable>]

Vamos a comenzar escribiendo la larga expresión condicional .. if .. else .. para obtener cuadrados de números pares y cubos de números impares de un rango dado.

1
squares_cubes = []
2
3
for n in range(1,16):
4
    if n%2 == 0:
5
        squares_cubes.append(n**2)
6
    else:
7
        squares_cubes.append(n**3)
8
        
9
print(squares_cubes)
10
# [1, 4, 27, 16, 125, 36, 343, 64, 729, 100, 1331, 144, 2197, 196, 3375]

La expresión condicional anterior tiene la siguiente estructura:

1
for <the_element> in <the_iterable>:
2
    if <the_condition>:
3
        <the_expression>
4
    else:
5
        <other_expression>

Poniendo los valores correspondientes en los lugares adecuados te dará la siguiente comprensión de lista:

1
squares_cubes = [n**2 if n%2 == 0 else n**3 for n in range(1,16)]
2
3
print(squares_cubes)
4
# [1, 4, 27, 16, 125, 36, 343, 64, 729, 100, 1331, 144, 2197, 196, 3375]

Comprensiones de Lista para Bucles Anidados

También puedes usar bucles anidados dentro de una comprensión de lista. No hay limite en el numero de bucles for que puedes poner dentro de una comprensión de lista. Sin embargo, tendrás que mantener en mente que el orden de los bucles debería de ser el mismo en ambos casos, en el código original y en la comprensión de lista. También puedes agregar una condición opcional if luego de cada bucle for. Una comprensión de lista con bucles for anidados tendrá la siguiente estructura:

1
[ <the_expression> for <element_a> in <iterable_a> (optional if <condition_a>)
2
                   for <element_b> in <iterable_b> (optional if <condition_b>)
3
                   for <element_c> in <iterable_c> (optional if <condition_c>)
4
                   ... and so on ...]

Los siguientes ejemplos deberían de hacer todo claro. Hay dos bucles anidados, y multiplicarlos juntos nos dará tablas de multiplicación.

1
multiplications = []
2
3
for i in range(1, 4):
4
    for n in range(1, 11):
5
        multiplications.append(i*n)
6
7
print(multiplications)
8
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30] 

Estos bucles for anidados pueden ser reescritos como:

1
for <element_a> in <iterable_a>:
2
    for <element_b> in <iterable_b>:
3
        <the_expression>

Una vez que has escrito el bucle en esta forma, convertirlo a una comprensión de lista es fácil:

1
multiplications = [i*n for i in range(1,4) for n in range(1,11)]
2
3
print(multiplications)
4
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30]

Puedes también usar una comprensión de lista escrita similarmente para aplanar una lista de listas. El bucle for externo itera a través de listas individuales y las guarda en la variable row. El loop for interno entonces iterará a través de todos los elementos en la row actual. Durante esta iteración, la variable row tiene el valor [1, 2, 3, 4]. El segundo loop itera a través de esta lista o row y agrega todos estos valores a la lista final.

1
matrix = [
2
    [1, 2, 3, 4],
3
    [5, 6, 7, 8],
4
    [9, 10, 11, 12],
5
]
6
7
flatten = [n for row in matrix for n in row]
8
9
print(flatten)
10
#[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

Comprensiones de Lista Anidadas

Las comprensiones de listas anidadas pueden sonar similares a las comprensiones de listas con bucles anidados, pero son muy diferentes. En el primero caso, estuviste tratando con bucles dentro de bucles. En este caso, estarás tratando con comprensiones de listas dentro de comprensiones de listas. Un buen ejemplo del uso de comprensiones de listas anidadas sería la creación de una transposición de la matriz para la sección anterior.

Sin una expresión de comprensión de lista, necesitarás usar dos bucles for para crear la transposición.

1
matrix = [
2
    [1, 2, 3, 4],
3
    [5, 6, 7, 8],
4
    [9, 10, 11, 12],
5
]
6
7
transpose = []
8
9
for i in range(4):
10
    temp = []
11
  for row in matrix:
12
		temp.append(row[i])
13
	transpose.append(temp)
14
    
15
print(transpose)
16
# [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

El bucle exterior itera a través de la matriz cuatro veces porque hay cuatro columnas en ella. El bucle interno itera a través de los elementos dentro de la fila actual un indice a la vez y lo agrega a una lista temporal llamada temp. La lista temp es entonces agregada como una fila a la matriz transpuesta. En el caso de las comprensiones de lista, el bucle de afuera viene al final y el bucle interior viene al inicio.

Aquí está el código anterior en forma de una comprensión de lista:

1
matrix = [
2
    [1, 2, 3, 4],
3
    [5, 6, 7, 8],
4
    [9, 10, 11, 12],
5
]
6
7
transpose = [[row[n] for row in matrix] for n in range(4)]
8
9
print(transpose)
10
# [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

Otra forma de ver esto es considerando la estructura de comprensiones de lista que reemplazan los bucles básicos for que aprendiste al inicio del artículo.

1
[<the_expression> for <the_element> in <the_iterable>]

Si lo comparas con la comprensión de lista anidada anterior, verás que <the_expression> en este caso es en realidad otra comprensión de lista: [row[n] for row in matrix]. Esta comprensión de lista anidada misma está en la forma de un bucle for básico.

Ideas Finales

Espero que este tutorial te haya ayudado a entender qué son las comprensiones de lista y como usarlas en lugar de bucles for básicos para escribir código conciso y ligeramente más rápido para la creación de listas.

Y otra cosa que deberías de mantener en mente es la legibilidad de tu código. La creación de comprensiones de lista para bucles anidados hará probablemente el código menos legible. En tales casos, puedes dividir la comprensión de lista en multiples lineas para mejorar la legibilidad.

Adicionalmente, no dudes en ver qué tenemos disponible para venta y para estudio en Envato Market, y no dudes en preguntar cualquier cosa y proveer de tu valiosos comentarios abajo.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.