Listas¶
(1)
Las listas permiten almacenar objetos mediante un orden definido y con posibilidad de duplicados. Las listas son estructuras de datos mutables, lo que significa que podemos añadir, eliminar o modificar sus elementos.
Creando listas¶
Una lista está compuesta por cero o más elementos. En Python debemos escribir estos elementos separados por comas y dentro de corchetes.
Veamos algunos ejemplos de listas:
>>> languages = ['Python', 'Ruby', 'Javascript']#(1)!
>>> fibonacci = [0, 1, 1, 2, 3, 5, 8, 13]#(2)!
>>> empty_list = []#(3)!
>>> data = [#(4)!
... 'Tenerife',
... {'cielo': 'limpio', 'temp': 24},
... 3718,
... (28.2933947, -16.5226597)
... ]
- Una lista de 3 cadenas de texto.
- Una lista de 8 números enteros.
- La lista vacía (0 elementos).
- Una lista heterogénea de 4 elementos de distinta naturaleza.
Datos heterogéneos
Una lista en Python puede contener datos heterogéneos a diferencia de otros lenguajes de programación. Esto hace de la lista una estructura de datos muy versátil.
Ejercicio
Entra en el intérprete interactivo de Python ❯❯❯ y crea una lista con las 5 ciudades que más te gusten.
Conversión¶
Para convertir otros tipos de datos en una lista podemos usar la función list()
. Por ejemplo podemos convertir una cadena de texto en una lista:
Si nos fijamos en lo que ha pasado, al convertir la cadena de texto Python se ha creado una lista con 6 elementos, donde cada uno de ellos representa un carácter de la cadena. Podemos extender este comportamiento a cualquier otro tipo de datos que permita ser iterado (iterables).
Otro ejemplo interesante de conversión puede ser la de los rangos. En este caso queremos obtener una lista explícita con los valores que constituyen el rango \([0,9]\):
Nombre de variable
Aunque está permitido, no suele ser una buena práctica llamar list
a una variable ya que destruirías la función que nos permite trabajar con listas. Tampoco parece muy razonable utilizar nombres como <algo>_list
o list_<algo>
ya que no es necesario incluir en el nombre de una variable su propia naturaleza.
Operaciones con listas¶
Existen multitud de operaciones que se pueden realizar sobre listas. A continuación veremos la mayoría de ellas:
Obtener un elemento¶
Igual que en el caso de las cadenas de texto, podemos obtener un elemento de una lista a través del índice (lugar) que ocupa. Veamos un ejemplo:
>>> shopping = ['Agua', 'Huevos', 'Aceite']
>>> shopping[0]
'Agua'
>>> shopping[1]
'Huevos'
>>> shopping[2]
'Aceite'
>>> shopping[-1]#(1)!
'Aceite'
- ¡Aquí también funcionan los índices negativos!
El índice que usemos para acceder a los elementos de una lista tiene que estar comprendido entre los límites de la misma. Si usamos un índice antes del comienzo o después del final obtendremos un error (excepción):
>>> shopping = ['Agua', 'Huevos', 'Aceite']
>>> shopping[3]
Traceback (most recent call last):
Cell In[2], line 1
shopping[3]
IndexError: list index out of range
>>> shopping[-5]
Traceback (most recent call last):
Cell In[3], line 1
shopping[-5]
IndexError: list index out of range
Trocear una lista¶
El troceado de listas funciona de manera totalmente análoga al troceado de cadenas. Veamos algunos ejemplos:
>>> shopping = ['Agua', 'Huevos', 'Aceite', 'Sal', 'Limón']
>>> shopping[:3]#(1)!
['Agua', 'Huevos', 'Aceite']
>>> shopping[2:4]
['Aceite', 'Sal']
>>> shopping[-1:-4:-1]
['Limón', 'Sal', 'Aceite']
>>> shopping[::-1]#(2)!
['Limón', 'Sal', 'Aceite', 'Huevos', 'Agua']
- También podríamos haber escrito
shopping[0:3]
aunque no es habitual. - Equivale a invertir la lista.
En el troceado de listas, a diferencia de lo que ocurre al obtener elementos, no debemos preocuparnos por acceder a índices inválidos (fuera de rango) ya que Python los restringirá a los límites de la lista:
>>> shopping
['Agua', 'Huevos', 'Aceite', 'Sal', 'Limón']
>>> shopping[10:]
[]
>>> shopping[-100:2]
['Agua', 'Huevos']
>>> shopping[2:100]
['Aceite', 'Sal', 'Limón']
Ninguna de las operaciones anteriores modifican la lista original, simplemente devuelven una lista nueva.
Invertir una lista¶
Python nos ofrece varios mecanismos para invertir los elementos de una lista, en función del resultado que busquemos:
-
Opcion A Mediante troceado de listas con «step» negativo:
-
Opcion B Mediante la función
reversed()
:
Añadir al final de la lista¶
Una de las operaciones más utilizadas en listas es añadir elementos al final de las mismas. Para ello Python nos ofrece la función append()
. Se trata de un método «destructivo» que modifica la lista original.
Veamos un ejemplo donde añadimos un producto a la lista de la compra:
>>> shopping = ['Agua', 'Huevos', 'Aceite']
>>> shopping.append('Atún')
>>> shopping
['Agua', 'Huevos', 'Aceite', 'Atún']
Patrón creación¶
Una forma muy habitual de trabajar con listas es empezar con una vacía e ir añadiendo elementos poco a poco. Se podría hablar de un patrón creación.
Supongamos un ejemplo en el que queremos construir una lista con los números pares en el intervalo \([0,20]\):
>>> even_numbers = []
>>> for num in range(20 + 1):#(1)!
... if num % 2 == 0:
... even_numbers.append(num)
...
>>> even_numbers
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
- Para «llegar» al 20 hay que incrementar en una unidad.
Añadir en cualquier posición¶
Ya hemos visto cómo añadir elementos al final de una lista. Sin embargo, Python ofrece una función insert()
que vendría a ser una generalización de la anterior, para incorporar elementos en cualquier posición.
Simplemente debemos especificar el índice de inserción y el elemento a insertar. También se trata de una función destructiva.
En el siguiente ejemplo insertamos dos nuevos productos a la lista de la compra en posiciones arbitrarias:
>>> shopping = ['Agua', 'Huevos', 'Aceite']
>>> shopping.insert(1, 'Jamón')#(1)!
>>> shopping
['Agua', 'Jamón', 'Huevos', 'Aceite']
>>> shopping.insert(3, 'Queso')#(2)!
>>> shopping
['Agua', 'Jamón', 'Huevos', 'Queso', 'Aceite']
- Se podría leer como: «Quiero que
'Jamón'
quede en la posición 1 de la lista». - Se podría leer como: «Quiero que
'Queso'
quede en la posición 3 de la lista».
Al igual que ocurría con el troceado de listas, en este tipo de inserciones no obtendremos un error si especificamos índices fuera de los límites de la lista. Estos se ajustarán al principio o al final en función del valor que indiquemos:
>>> shopping = ['Agua', 'Huevos', 'Aceite']
>>> shopping.insert(100, 'Mermelada')#(1)!
>>> shopping
['Agua', 'Huevos', 'Aceite', 'Mermelada']
>>> shopping.insert(-100, 'Arroz')#(2)!
>>> shopping
['Arroz', 'Agua', 'Huevos', 'Aceite', 'Mermelada']
- Se inserta lo más a la «derecha» posible.
- Se inserta lo más a la «izquierda» posible.
append vs insert
Podría existir la tentación de utilizar insert()
para añadir elementos al final de una lista...
¡No lo hagas! Utiliza append()
Es más eficiente y más legible.
Repetir elementos¶
Al igual que con las cadenas de texto, el operador *
nos permite repetir los elementos de una lista.
Siguiendo con el ejemplo de la lista de la compra, podríamos querer comprar 3 unidades de cada producto:
>>> shopping = ['Agua', 'Huevos', 'Aceite']
>>> shopping * 3
['Agua',
'Huevos',
'Aceite',
'Agua',
'Huevos',
'Aceite',
'Agua',
'Huevos',
'Aceite']
Combinar listas¶
Python nos ofrece varios mecanismos para combinar dos listas, en función del resultado que busquemos:
Mediante el operador +
:
Hay que tener en cuenta que extend()
funciona adecuadamente si pasamos una lista como argumento. En otro caso, quizás los resultados no sean los esperados.
Veamos un ejemplo:
>>> shopping = ['Agua', 'Huevos', 'Aceite']
>>> shopping.extend('Limón')#(1)!
>>> shopping
['Agua', 'Huevos', 'Aceite', 'L', 'i', 'm', 'ó', 'n']
-
extend()
«recorre» (o itera) sobre cada uno de los elementos del objeto en cuestión.- Al ser una cadena de texto cada elemento es un carácter.
Se podría pensar en utilizar append()
para combinar listas. La realidad es que no funciona exactamente como esperamos; la segunda lista se añadiría como una sublista de la principal.
Veamos un ejemplo:
>>> shopping = ['Agua', 'Huevos', 'Aceite']
>>> fruitshop = ['Naranja', 'Manzana', 'Piña']
>>> shopping.append(fruitshop)
>>> shopping
['Agua', 'Huevos', 'Aceite', ['Naranja', 'Manzana', 'Piña']]
Modificar listas¶
Para modificar un elemento de una lista debemos acceder a su índice y asignar el valor correspondiente.
En el siguiente ejemplo preferimos comprar jugo que agua:
>>> shopping = ['Agua', 'Huevos', 'Aceite']
>>> shopping[0]
'Agua'
>>> shopping[0] = 'Jugo'
>>> shopping
['Jugo', 'Huevos', 'Aceite']
En el caso de acceder a un índice no válido de la lista, incluso para modificar, obtendremos un error:
>>> shopping[100]
Traceback (most recent call last):
Cell In[1], line 1
shopping[100]
IndexError: list index out of range
Modificar con troceado¶
No sólo es posible modificar un elemento de cada vez, sino que podemos asignar valores a trozos de una lista.
En el siguiente ejemplo reemplazamos huevos, aceite y sal por atún y pasta:
>>> shopping = ['Agua', 'Huevos', 'Aceite', 'Sal', 'Limón']
>>> shopping[1:4]
['Huevos', 'Aceite', 'Sal']
>>> shopping[1:4] = ['Atún', 'Pasta']#(1)!
>>> shopping
['Agua', 'Atún', 'Pasta', 'Limón']
- La lista que asignamos no necesariamente debe tener la misma longitud que el trozo que sustituimos.
Borrar elementos¶
Python nos ofrece varios mecanismos para borrar elementos de una lista:
Mediante la sentencia del
:
Mediante la función remove()
:
>>> shopping = ['Agua', 'Huevos', 'Aceite', 'Sal', 'Limón']
>>> shopping.remove('Sal')#(1)!
>>> shopping
['Agua', 'Huevos', 'Aceite', 'Limón']
- Si existen valores duplicados, la función
remove()
sólo borarrá la primera ocurrencia.
La sentencia del
y la función remove()
efectivamente borran el elemento indicado de la lista, pero no «devuelven»1 nada. Sin embargo, Python nos ofrece la función pop()
que además de borrar, nos «recupera» el elemento; algo así como una extracción. Lo podemos ver como una combinación de acceso + borrado:
>>> shopping = ['Agua', 'Huevos', 'Aceite', 'Sal', 'Limón']
>>> product = shopping.pop()#(1)!
>>> product
'Limón'
>>> shopping
['Agua', 'Huevos', 'Aceite', 'Sal']
>>> product = shopping.pop(2)#(2)!
>>> product
'Aceite'
>>> shopping
['Agua', 'Huevos', 'Sal']
- Cuando no se indica el índice, Python extrae en último elemento. Equivale a:
shopping.pop(-1)
- Extraer el elemento en la posición 2.
Mediante troceado de listas:
Borrado completo de la lista¶
Python nos ofrece varios mecanismos para borrar una lista por completo:
Recolector de basura
La memoria que queda «en el limbo» después de asignar un nuevo valor a la lista es detectada por el recolector de basura de Python, quien se encarga de liberar aquellos datos que no están referenciados por ninguna variable.
Encontrar un elemento¶
Si queremos descubrir el índice que corresponde a un determinado valor dentro una lista debemos usar la función index()
.
Como ejemplo supongamos que queremos encontrar el aceite en nuestra lista de la compra:
Hay que tener en cuenta que si el elemento que buscamos no está en la lista, obtendremos un error:
>>> shopping = ['Agua', 'Huevos', 'Aceite', 'Sal', 'Limón']
>>> shopping.index('Pollo')
Traceback (most recent call last):
Cell In[2], line 1
shopping.index('Pollo')
ValueError: 'Pollo' is not in list
Múltiples ocurrencias
Si buscamos un valor que existe más de una vez en una lista, la función index()
sólo nos devolverá el índice de la primera ocurrencia.
No existe find
En listas no disponemos de la función find()
que sí estaba disponible para cadenas de texto.
Pertenencia de un elemento¶
Si queremos comprobar la existencia de un determinado elemento en una lista, podríamos buscar su índice, pero la forma pitónica de hacerlo es utilizar el operador in
.
Si no estamos seguros de si hemos incluido ciertos productos en nuestro ejemplo de la lista de la compra, lo podemos comprobar de la siguiente manera:
>>> shopping = ['Agua', 'Huevos', 'Aceite', 'Sal', 'Limón']
>>> 'Aceite' in shopping
True
>>> 'Pollo' in shopping
False
Valor booleano
El operador in
siempre devuelve un valor booleano, es decir, verdadero o falso.
Ejercicio
pypas isogram
Longitud de una lista¶
Podemos conocer el número de elementos que tiene una lista mediante la función len()
.
Por ejemplo para conocer la cantidad de productos de nuestra lista de la compra haríamos lo siguiente:
Número de ocurrencias¶
Para contar cuántas veces aparece un determinado valor dentro de una lista podemos usar la función count()
.
Un ejemplo «divertido» de la serie The Big Bang Theory:
>>> sheldon_greeting = ['Penny', 'Penny', 'Penny']
>>> sheldon_greeting.count('Howard')
0
>>> sheldon_greeting.count('Penny')
3
Dividir «string» como lista¶
Una tarea muy habitual al trabajar con cadenas de texto es dividirlas por algún tipo de separador. En este sentido, Python nos ofrece la función split()
, que debemos usar anteponiendo el «string» que queramos dividir.
Veamos un ejemplo con ciertos refranes:
>>> proverb = 'No hay mal que por bien no venga'
>>> proverb.split()#(1)!
['No', 'hay', 'mal', 'que', 'por', 'bien', 'no', 'venga']
>>> tools = 'Martillo,Sierra,Destornillador'
>>> tools.split(',')#(2)!
['Martillo', 'Sierra', 'Destornillador']
- Si no se indica nada, la función
split()
usa por defecto cualquier secuencia de espacios en blanco, tabuladores y saltos de línea como separador. - En este caso se ha indicado que el separador sea una coma.
Existe una variante de split()
en la que indicamos el número máximo de divisiones. Supongamos un ejemplo en el que nos dan una URL y nos piden separar el dominio de la ruta:
>>> url = 'python.org/downloads/releases'
>>> url.split('/')#(1)!
['python.org', 'downloads', 'releases']
>>> url.split('/', 1)#(2)!
['python.org', 'downloads/releases']
- Aquí
split()
no nos está sirviendo mucho... - Al indicar el máximo de «una división» hemos conseguido el resultado.
También existe la función rsplit()
que se comporta exactamente igual que la función split()
pero empezando por la derecha.
Ejercicio
pypas num-words
Particionado de cadenas de texto¶
Existe una forma algo más «elaborada» de dividir una cadena a través del particionado. Para ello podemos valernos de la función partition()
que proporciona Python.
Esta función toma un argumento como separador, y divide la cadena de texto en 3 partes: lo que queda a la izquierda del separador, el separador en sí mismo y lo que queda a la derecha del separador
Veamos un ejemplo muy sencillo a partir de una operación matemática:
También existe la función rpartition()
que se comporta exactamente igual que la función partition()
pero empezando por la derecha.
Unir lista como «string»¶
Dada una lista, podemos convetirla a una cadena de texto, uniendo todos sus elementos mediante algún separador. Para ello hacemos uso de la función join()
con la siguiente estructura:
Veamos varios ejemplos uniendo los productos de la lista de la compra:
>>> shopping = ['Agua', 'Huevos', 'Aceite', 'Sal', 'Limón']
>>> ','.join(shopping)
'Agua,Huevos,Aceite,Sal,Limón'
>>> ' '.join(shopping)
'Agua Huevos Aceite Sal Limón'
>>> '|'.join(shopping)
'Agua|Huevos|Aceite|Sal|Limón'
Hay que tener en cuenta que join()
sólo funciona si todos sus elementos son cadenas de texto:
>>> ', '.join([1, 2, 3, 4, 5])
Traceback (most recent call last):
Cell In[1], line 1
', '.join([1, 2, 3, 4, 5])
TypeError: sequence item 0: expected str instance, int found
join vs split
La función join()
es realmente la opuesta a la función split().
Ejercicio
pypas fix-date
Ordenar una lista¶
Python nos ofrece varios mecanismos para ordenar una lista:
Ambos métodos admiten un parámetro «booleano» reverse
para indicar si queremos que la ordenación se haga en sentido inverso:
>>> shopping = ['Agua', 'Huevos', 'Aceite', 'Sal', 'Limón']
>>> sorted(shopping, reverse=True)
['Sal', 'Limón', 'Huevos', 'Agua', 'Aceite']
Iterar sobre una lista¶
Al igual que hemos visto con las cadenas de texto, también podemos iterar sobre los elementos de una lista utilizando la sentencia for
.
Recorremos por ejemplo los productos de la lista de la compra:
>>> shopping = ['Agua', 'Huevos', 'Aceite', 'Sal', 'Limón']
>>> for product in shopping:
... print(product)
...
Agua
Huevos
Aceite
Sal
Limón
break y continue
En esta estructura también es posible utilizar tanto break
como continue
.
Ejercicio
pypas chars-list
Iterar usando enumeración¶
Hay veces que no sólo nos interesa «visitar» cada uno de los elementos de una lista, sino que también queremos saber su índice dentro de la misma. Para ello Python nos ofrece la función enumerate()
.
Para el ejemplo de la lista de la compra, nos podría interesar aplicar esta estructura programática:
>>> shopping = ['Agua', 'Huevos', 'Aceite', 'Sal', 'Limón']
>>> for index, product in enumerate(shopping):#(1)!
... print(index, product)
...
0 Agua
1 Huevos
2 Aceite
3 Sal
4 Limón
- En cada iteración del bucle las variables
index
yproduct
reciben el índice y el producto existentes en la lista de la compra.
Por defecto enumerate()
empieza sus índices en 0 (como era de esperar) pero si quisiéramos modificar este comportamiento también se podría.
Ejemplo empezando la enumeración de la lista de la compra en 10:
>>> shopping = ['Agua', 'Huevos', 'Aceite', 'Sal', 'Limón']
>>> for index, product in enumerate(shopping, 10):
... print(index, product)
...
10 Agua
11 Huevos
12 Aceite
13 Sal
14 Limón
Iterar sobre múltiples listas¶
Python ofrece la posibilidad de iterar sobre múltiples listas en paralelo utilizando la función zip()
. Se basa en ir «juntando» ambas listas elemento a elemento:
Veamos un ejemplo en el que añadimos ciertos detalles a nuestra lista de la compra:
>>> shopping = ['Agua', 'Aceite', 'Arroz']
>>> details = ['mineral natural', 'de oliva virgen', 'basmati']
>>> for product, detail in zip(shopping, details):#(1)!
... print(product, detail)
...
Agua mineral natural
Aceite de oliva virgen
Arroz basmati
- En cada iteración del bucle la variable
product
toma un elemento de la listashopping
y la variabledetail
toma un elemento de la listadetails
.
Distinta longitud
En el caso de que las listas no tengan la misma longitud, la función zip()
realiza la combinación hasta que se agota la lista más corta.
Dado que zip()
produce un iterador, si queremos obtener una lista explícita con la combinación en paralelo de las listas, debemos construir dicha lista de la siguiente manera:
>>> shopping = ['Agua', 'Aceite', 'Arroz']
>>> details = ['mineral natural', 'de oliva virgen', 'basmati']
>>> list(zip(shopping, details))
[('Agua', 'mineral natural'),
('Aceite', 'de oliva virgen'),
('Arroz', 'basmati')]
Ejercicio
pypas dot-product
Comparar listas¶
¿Cómo determina Python si una lista es mayor o menor que otra? Analicemos lo que ocurre en el siguiente ejemplo:
Python llega a la conclusión de que la lista [1, 2, 3]
es menor que [1, 2, 4]
porque va comparando elemento a elemento:
- El
1
es igual en ambas listas. - El
2
es igual en ambas litas. - El
3
es menor que el4
, por lo que la primera lista es menor que la segunda.
Entender la forma en la que se comparan dos listas es importante para poder aplicar otras funciones y obtener los resultados deseados.
Ver también
Esta comparación funciona de forma totalmente análoga a la comparación de cadenas de texto.
Cuidado con las copias¶
Las listas son estructuras de datos mutables y esta característica nos obliga a tener cuidado cuando realizamos copias de listas, ya que la modificación de una de ellas puede afectar a la otra.
Veamos un ejemplo sencillo:
>>> original_list = [4, 3, 7, 1]
>>> copy_list = original_list#(1)!
>>> original_list[0] = 15#(2)!
>>> original_list#(3)!
[15, 3, 7, 1]
>>> copy_list#(4)!
[15, 3, 7, 1]
- Con esta asignación hacemos que
copy_list
«apunte» a la misma zona de memoria queoriginal_list
. - En esa zona de memoria estamos modificando el primer elemento de la lista
original_list
. - Obviamente esta lista se habrá modificado.
- También se ha modificado la «copia».
Una posible solución a este problema sería efectuar una «copia dura». Para ello Python proporciona la función copy()
:
>>> original_list = [4, 3, 7, 1]
>>> copy_list = original_list.copy()#(1)!
>>> original_list[0] = 15#(2)!
>>> original_list#(3)!
[15, 3, 7, 1]
>>> copy_list#(4)!
[4, 3, 7, 1]
-
- La función
copy()
hace una copia en otra zona de memoria. - Aquí también valdría utilizar un troceado «completo»
copy_list = original_list[:]
- La función
- Modificamos el primer elemento de
original_list
. - La modificación de este elemento sólo afecta a
original_list
. - Dado que
copy_list
está en otra zona de memoria no se ve afectada por el cambio.
Copia profunda
En el caso de que estemos trabajando con listas que contienen elementos mutables, debemos hacer uso de la función deepcopy()
dentro del módulo copy
de la librería estándar.
Veracidad múltiple¶
Si bien podemos usar sentencias condicionales para comprobar la veracidad de determinadas expresiones, Python nos ofrece dos funciones «built-in» con las que podemos evaluar si se cumplen todas las condiciones all()
o si se cumple alguna condición any()
. Estas funciones trabajan sobre iterables, y el caso más evidente es una lista.
Supongamos un ejemplo en el que queremos comprobar si una determinada palabra cumple las siguientes condiciones:
- Su longitud total es mayor que 4.
- Empieza por «p».
- Contiene, al menos, una «y».
>>> word = 'python'
>>> enough_length = len(word) > 4#(1)!
>>> right_beginning = word.startswith('p')#(2)!
>>> min_ys = word.count('y') >= 1#(3)!
>>> is_cool_word = all([enough_length, right_beginning, min_ys])#(4)!
>>> if is_cool_word:
... print('Cool word!')
... else:
... print('No thanks')
...
Cool word!
True
True
True
all([True, True, True])
True
>>> word = 'yeah'
>>> enough_length = len(word) > 4#(1)!
>>> right_beginning = word.startswith('p')#(2)!
>>> min_ys = word.count('y') >= 1#(3)!
>>> is_fine_word = any([enough_length, right_beginning, min_ys])#(4)!
>>> if is_fine_word:
... print('Fine word!')
... else:
... print('No thanks')
...
Fine word!
False
False
True
any([False, False, True])
True
A tener en cuenta la peculiaridad de estas funciones cuando trabajan con la lista vacía:
Casos de uso
Este enfoque puede ser interesante cuando se manejan muchas condiciones o bien cuando queremos separar las condiciones y agruparlas en una única lista.
Listas por comprensión¶
Las listas por comprensión establecen una técnica para crear listas de forma más compacta basándose en el concepto matemático de conjuntos definidos por comprensión.
Podríamos decir que su sintaxis sigue un modelo VLC (Value-Loop-Condition) tal y como se muestra en la siguiente figura:
Empecemos por un ejemplo en el que convertimos una cadena de texto con valores numéricos en una lista con los mismos valores pero convertidos a enteros:
A continuación se presenta un diagrama con la transformación de la estructura clásica en listas por comprensión:
Condiciones en comprensiones¶
También existe la posibilidad de incluir condiciones en las listas por comprensión.
Continuando con el ejemplo anterior, supongamos que sólo queremos crear la lista con aquellos valores que empiecen por el dígito 4:
>>> values = '32,45,11,87,20,48'
>>> int_values = [int(v) for v in values.split(',') if v.startswith('4')]
>>> int_values
[45, 48]
Anidamiento en comprensiones¶
En la iteración que usamos dentro de la lista por comprensión es posible usar bucles anidados.
Veamos un ejemplo en el que generamos todas las combinaciones de una serie de valores:
>>> values = '32,45,11,87,20,48'
>>> svalues = values.split(',')
>>> combinations = [f'{v1}x{v2}' for v1 in svalues for v2 in svalues]
>>> combinations
['32x32',
'32x45',
'32x11',
'32x87',
'32x20',
'32x48',
'45x32',
'45x45',
...
'48x45',
'48x11',
'48x87',
'48x20',
'48x48']
Casos de uso
Las listas por comprensión son una herramienta muy potente y nos ayuda en muchas ocasiones, pero hay que tener cuidado de no generar expresiones excesivamente complejas. En estos casos es mejor una aproximación clásica.
Ejercicio
pypas fcomp
sys.argv
¶
Cuando queramos ejecutar un programa Python desde línea de comandos, tendremos la posibilidad de acceder a los argumentos de dicho programa. Para ello se utiliza una lista «especial» que la encontramos dentro del módulo sys
y que se denomina argv
:
Veamos una aplicación de lo anterior en un ejemplo que convierte un número decimal a una determinada base, ambos argumentos pasados por línea de comandos:
import sys
number = int(sys.argv[1])#(1)!
tobase = int(sys.argv[2])#(2)!
match tobase:
case 2:
result = f'{number:b}'
case 8:
result = f'{number:o}'
case 16:
result = f'{number:x}'
case _:
result = None
if result is None:
print(f'Base {tobase} not implemented!')
else:
print(result)
- El
primersegundo argumento es el número a convertir. - El
segundotercer argumento es la base a la que convertir.
Si lo ejecutamos obtendríamos lo siguiente:
Funciones matemáticas¶
Python nos ofrece, entre otras2, estas tres funciones matemáticas básicas que se pueden aplicar sobre listas.
Ejercicio
Escribe un programa avg.py
que reciba desde línea de comandos una serie de números y calcule la media de dichos valores (redondeando a 2 cifras decimales).
La llamada se haría de la siguiente manera:
Ejemplo:
- Entrada
32 56 21 99 12 17
- Salida
40.17
Ten en cuenta que sys.argv
es una lista (como otra cualquiera) y que admite troceado de listas.
Lista de listas¶
Como ya hemos visto en varias ocasiones, las listas son estructuras de datos que pueden contener elementos heterogéneos. Estos elementos pueden ser a su vez listas.
A continuación planteamos un ejemplo del contexto deportivo. Un equipo de fútbol suele tener una disposición en el campo organizada en líneas de jugadores/as. En aquella alineación con la que España ganó la copa del mundo en 2023 había una disposición 4-3-3 con las siguientes jugadoras:
Veamos una posible representación de este equipo de fútbol usando una lista compuesta de listas. Primero definimos cada una de las líneas:
>>> goalkeeper = 'Cata'
>>> defenders = ['Olga', 'Laia', 'Irene', 'Ona']
>>> midfielders = ['Jenni', 'Teresa', 'Aitana']
>>> forwards = ['Mariona', 'Salma', 'Alba']
Y ahora las juntamos en una única lista:
>>> team = [goalkeeper, defenders, midfielders, forwards]
>>> team
['Cata',
['Olga', 'Laia', 'Irene', 'Ona'],
['Jenni', 'Teresa', 'Aitana'],
['Mariona', 'Salma', 'Alba']]
Podemos comprobar el acceso a distintos elementos:
>>> team[0]#(1)!
'Cata'
>>> team[1][0]#(2)!
'Olga'
>>> team[2]#(3)!
['Jenni', 'Teresa', 'Aitana']
>>> team[3][1]#(4)!
'Salma'
- Portera.
- Lateral izquierdo.
- Centrocampistas.
- Delantera centro.
También podemos recorrer toda la alineación:
>>> for playline in team:
... if isinstance(playline, list):#(1)!
... for player in playline:
... print(player, end=' ')
... print()
... else:
... print(playline)
...
Cata
Olga Laia Irene Ona
Jenni Teresa Aitana
Mariona Salma Alba
- Es necesario comprobar si es una lista porque la portera está «sola».
Ejercicio
pypas mul-matrix2
Ejercicios¶
- pypas
max-value
- pypas
max-value-with-min
- pypas
min-value
- pypas
min-value-with-max
- pypas
remove-dups
- pypas
flatten-list
- pypas
remove-consecutive-dups
- pypas
all-same
- pypas
sum-diagonal
- pypas
powers2
- pypas
dec2bin
- pypas
sum-mixed
- pypas
n-multiples
- pypas
drop-even
- pypas
nth-power
- pypas
name-initials
- pypas
non-consecutive
- pypas
mul-reduce
- pypas
digit-rev-list
- pypas
time-plus-minutes
- pypas
add-positives
- pypas
add-opposites
- pypas
descending-numbers
- pypas
merge-sorted
- pypas
trimmed-add
- pypas
wolves
- pypas
minmax
- pypas
cascading-subsets
- pypas
diff-cuboid
- pypas
fl-strip
- pypas
logical-chain
- pypas
first-unused-id
- pypas
find-odds
- pypas
chemistry
- pypas
next-item
- pypas
v-partition
- pypas
attach-len
- pypas
reversing-words
- pypas
barycenter
- pypas
sort-custom
- pypas
flatten-list-deep
- pypas
first-duplicated
- pypas
fill-values
- pypas
frange
- pypas
qual-name
- pypas
mul-matrix