Autor: Luis Fernando Apáez Álvarez
-Curso PyM-
Clase 5: Colecciones I
Fecha: 12 de Agosto del 2022
Dentro de Python podemos manejar diversas estructuras de datos, las cuales pueden entenderse de manera intuitiva como un cierto tipo de dato compuesto, pues ésta puede almacenar datos de diferentes tipos. Así, la primer estructura de datos que abordaremos son las listas
Si bien en clases anteriores o tareas hemos abordado ya los conceptos más básicos, en esta sección indagaremos con un poco más de profundidad sobre ellas. Inicialmente, recordemos que una lista puede tener elementos de distintos tipos de datos
# lista con elementos de diferentes tipos de datos
lista_mix = ["Esto es una cadena de texto", 1, 3.1416, True, ":D"]
# imprimimos cada uno de sus elementos.
# recordemos que la variable del for la podemos
# llamar como queramos. En particular, podemos emplear
# el guion bajo el cual representara a la variable del
# siguiente for.
# al guion bajo como variable del for se le conoce
# como variable muda
for _ in lista_mix:
print(_, end=", ")
Esto es una cadena de texto, 1, 3.1416, True, :D,
También recordemos que podemos acceder a sus elementos mediante índices
for _ in range(len(lista_mix)):
print(lista_mix[_], end=", ")
Esto es una cadena de texto, 1, 3.1416, True, :D,
Podemos acceder de manera directa al último elemento de una lista utilizando el índice -1:
# ultimo elemento de nuestra lista
print(lista_mix[-1])
print()
# penultimo elemento de nuestra lista
print(lista_mix[-2])
# y podemos continuar asi de manera sucesiva,
# hasta llegar al primer elemento
print(lista_mix[-5])
:D True Esto es una cadena de texto
Podemos obtener más de un elemento de una lista a la vez. Por ejemplo, podemos obtener los primeros dos elementos
# el 2 no se contempla, en realidad estamos contemplando
# hasta el 1
print(lista_mix[0:2])
['Esto es una cadena de texto', 1]
donde hemos especificado que queremos del primer elemento (índice 0) al elemento segundo elemento (índice 1). El resultado de lo anterior nos arroja de nuevo una lista
sublista1 = lista_mix[0:2]
print(sublista1)
print()
print(type(sublista1))
['Esto es una cadena de texto', 1] <class 'list'>
la cual podemos considerar como una sublista de la lista original. También, podemos considerar otras sublistas como:
# del indice 2 al 4
# o tambien, del tercer elemento al quinto
sublista2 = lista_mix[2:5]
print(sublista2)
print()
# del indice 1 al 3
sublista3 = lista_mix[1:4]
print(sublista3)
[3.1416, True, ':D'] [1, 3.1416, True]
Si queremos los elementos de a partir de un índice y hasta el último elemento de la lista, no es necesario colocar el índice del último elemento. Por ejemplo, la sublista2
va del elemento del índice 2 hasta el último elemento de la lista, así, en vez de usar lista_mix[2:5]
podemos escribir simplemente
sublista2_2 = lista_mix[2:]
print(sublista2_2)
[3.1416, True, ':D']
Con lo cual obtenemos el mismo resultado. De manera análoga, si quieres todos los elementos a partir del primer elemento de una lista y hasta cierto índice, podemos omitir el índice cero. Por ejemplo, en vez de escribir
sublista1 = lista_mix[0:2]
podemos simplemente escribir
sublista1 = lista_mix[:2]
En efecto:
sublista1_2 = lista_mix[:2]
print(sublista1_2)
['Esto es una cadena de texto', 1]
Las listas son mutables, es decir, podemos cambiar su contenido. De tal manera, podremos cambiar sus elementos.
Para ello debemos utilizar el operador de asignación =
y el índice del elemento el cual queremos cambiar:
lista_mix = ["Esto es una cadena de texto", 1, 3.1416, True, ":D"]
print(lista_mix)
print()
# cambiaremos el True por un False
# el elemento True tiene el indice 3, por ende
lista_mix[3] = False
print(lista_mix)
['Esto es una cadena de texto', 1, 3.1416, True, ':D'] ['Esto es una cadena de texto', 1, 3.1416, False, ':D']
En vez de que nosotros calculemos de manera manual el índice de un elemento de una lista, así como lo hicimos antes para el ex elemento True
, podemos utilizar el método index()
para averiguar el índice que un elemento tiene dentro de una lista. Por ejemplo, hallemos el índice asociado al elemento False
en la lista lista_mix
:
print(lista_mix.index(False))
# o tambien, hallemos el indice del elemento :D
print()
print(lista_mix.index(":D"))
3 4
Gracias a este método podemos agregar elementos nuevos a nuestras listas. Por ejemplo
# Creamos una lista vacia
lista_vacia = []
print(lista_vacia)
print()
# Despues, usamos el metodo append()
# para agregar un elemento
lista_vacia.append("Hola")
print(lista_vacia)
print()
# ahora le agregaremos un booleano
lista_vacia.append(True)
print(lista_vacia)
[] ['Hola'] ['Hola', True]
Este método es bastante útil y representa una herramienta bastante versátil. Por ejemplo
lista1 = []
lista2 = []
# agregaremos los numeros del 0 al 10 en la lista1
# y sus cuadrados a la segunda lista
for i in range(11):
lista1.append(i)
lista2.append(i ** 2)
print(f"Lista 1: {lista1}")
print()
print(f"Lista 2: {lista2}")
Lista 1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Lista 2: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Podemos agregar nuevos elementos a nuestra lista, pero ahora especificando el índice de la lista donde agregaremos dicho elemento. Para ello ocuparemo ahora el método insert(, )
, donde en el primer parámetro colocamos el índice donde agregaremos nuestro nuevo elemento, y en el segundo parámetro el elemento a agregar.
Por ejemplo
# declaramos una lista
lista3 = ["Luis", 2, True]
print(f"Elemento de la lista3 en la posición 1: {lista3[1]}")
print()
# agregamos un nuevo valor en la posición 1
lista3.insert(1, "3.1416")
print(f"Elemento de la lista3 en la posición 1: {lista3[1]}")
Elemento de la lista3 en la posición 1: 2 Elemento de la lista3 en la posición 1: 3.1416
También podemos removeer elementos de una lista, lo cual conseguiremos utilizando el método remove()
. Por ejemplo, eliminemos el elemento 3.1416
de la lista lista3
print(lista3)
print()
# eliminemos el elemento 3.1416
lista3.remove("3.1416")
print(lista3)
['Luis', '3.1416', 2, True] ['Luis', 2, True]
Por otro lado, notemos que el método append()
agrega un elemento nuevo al final de una lista. De manera similar, podemos eliminar el último elemento de una lista utilizando el método pop()
, el cual no requiere que especifiquemos un parámetro.
# creamos una lista
lista4 = []
for i in range(4):
lista4.append(i)
print(lista4)
print()
# eliminamos el ultimo elemento de nuestra lista
lista4.pop()
print(lista4)
[0, 1, 2, 3] [0, 1, 2]
También, podemos ver si un elemento en particular pertenece o no a una lista
lista5 = [1, 3.1416, "Hola"]
# el elemento 1 esta en la lista5?
print(1 in lista5)
True
# el elemento "Hola" esta en la lista5?
print("Hola" in lista5)
print()
# el elemento "Mundo" esta en la lista5?
print("Mundo" in lista5)
print()
# el elemento 3 esta en la lista5?
print(3 in lista5)
True False False
Las tuplas son, en idea, muy similares a las listas, pero con algunas diferencias. La primer diferencia es que las listas son mutables, es decir que se pueden modificar, pero las tuplas no, esto es, la tuplas son inmutables. Podemos crear tuplas utilizando paréntesis en vez de corchetes:
# creamos nuestra primer tuplas
tupla1 = (1, "Luis", 0, False)
print(tupla1)
print()
print(type(tupla1))
(1, 'Luis', 0, False) <class 'tuple'>
Para las tuplas no tendremos un método como el append(), remove()
, etcétera, pues dichos métodos modificaban de alguna manera nuestras listas.
De tal manera, el uso de las tuplas surge cuando deseamos tener información que no queremos modificar, en principio. No obstante, podemos convertir tuplas a listas, de este modo, podremos modificar dicha lista y utilizar todo lo que aprendimos sobre listas; luego, también podemos convertir listas a tuplas. En resumen, si queremos modificar una tupla debemos convertirla a lista, y después de las modificaciones, convertiremos dicha lista a una tupla. Por ejemplo
# consideramos la tupla:
tupla2 = (1, 2, 3, 4, 5)
print(tupla2)
print()
print(type(tupla2))
print("-" * 30)
# para convertir una tupla a una lista utilizamos la
# funcion list() como sigue
lista_tupla2 = list(tupla2)
print(lista_tupla2)
print()
print(type(lista_tupla2))
(1, 2, 3, 4, 5) <class 'tuple'> ------------------------------ [1, 2, 3, 4, 5] <class 'list'>
Ahora, podemos modificar como ya sabemos la lista lista_tupla2
:
# agreguemos un nuevo elemento en la posicion 2
lista_tupla2[2] = 100
print(lista_tupla2)
print()
# despues, convertiremos dicha lista a una tupla
# para lo cual utilizaremos la funcion tuple()
# como sigue
tupla2_de_nuevo = tuple(lista_tupla2)
print(tupla2_de_nuevo)
print()
print(type(tupla2_de_nuevo))
[1, 2, 100, 4, 5] (1, 2, 100, 4, 5) <class 'tuple'>
De manera totalmente análoga a las listas, podemos acceder a los elementos de una tupla
# primer elemento de la tupla
print(tupla2_de_nuevo[0])
print()
# ultimo elemento de la tupla
print(tupla2_de_nuevo[-1])
1 5
y también podemos obtener subtuplas
# subtupla1: primeros dos elementos de la
# tupla tupla2_de_nuevo
subtupla1 = tupla2_de_nuevo[0:2]
print(subtupla1)
(1, 2)
Por otro lado, notemos que, de lista_tupla2 = [1, 2, 3, 4, 5]
, observamos que los elementos de dicha lista son números consecutivos, los cuales podemos generar fácilmente con un bucle for
como sigue
for i in range(1,6):
print(i)
1 2 3 4 5
O también, dada una lista vacía podemos ir agregando dichos elementos
lista_tupla2_2 = []
for i in range(1,6):
lista_tupla2_2.append(i)
print(lista_tupla2_2)
[1, 2, 3, 4, 5]
Existe otra manera más directa de realizar la acción que realizamos en la celda de código anterior:
En vez de que agregemos los elementos a nuestra lista vacía lista_tupla2_2
utilizando el bucle for
como lo hicimos antes, en realidad podemos definir listas utilizando un criterio mediante un bucle for
. Dichas listas se conocen como listas de comprensión.
Procedamos a crear nuestra primer lista de comprensión:
# Dentro de los corchetes de la siguiente lista
# lista_comp = [ ]
# escribiremos un bucle for como sigue
lista_comp = [ i for i in range(1,6)]
print(lista_comp)
[1, 2, 3, 4, 5]
donde los elementos de la lista lista_comp
serán los valores tal cual que toma la i
sobre el rango generado por el range(1,6)
Podemos ver otro ejemplo, donde ahora agregaremos los cuadrados de los números 1,2,3,4 y 5 en una nueva lista:
# Dentro de los corchetes de la siguiente lista
# lista_comp_2 = [ ]
# escribiremos un bucle for como sigue
lista_comp_2 = [ i ** 2 for i in range(1,6)]
print(lista_comp_2)
[1, 4, 9, 16, 25]
De donde:
Otro ejemplo. Podemos agregar todos los caracteres de una cdena de texto dada, en una lista utilizando el concepto de listas de comprensión :
# cadena
msj = "Mola Mundo"
# lista de omprension con todos los caracteres de
# la cadena anterior
# Podemos utilizar también variables mudas
lista_msj = [ _ for _ in msj]
print(lista_msj)
# Podemos regresar a la cadena original
# a partir de la lista anterior
msj2 = ""
for _ in lista_msj:
msj2 += _
print(msj2)
['M', 'o', 'l', 'a', ' ', 'M', 'u', 'n', 'd', 'o'] Mola Mundo
Escribamos ahora un programa para agregar números pares (a una lista) en cierto rango de números enteros. Recordemos que un número $x$ puede ser par si, al considera la división $\frac{x}{2}$ el residuo es cero; por ejemplo, el 4 es par pues de $\frac{4}{2}=2$, el residuo es cero; el 10 es par pues el residuo de $\frac{10}{2}$ es cero. Además, recordemos que el operador %
calcula el residuo de una división, por ejemplo
print(10 % 2)
print(11 % 2)
0 1
Asimismo, notemos que un número no es par si el residuo obtenido es distinto de cero. Como en el caso anterior donde el residuo de dividir $\frac{11}{2}$ fue 1. Así, escribimos:
# lista para almacenar los numero pares en un rango
pares = []
# utilizamos un for para recorrer un rango de numeros
for i in range(0, 11):
# implementamos un if para agregar a la lista pares
# justamente, los numeros pares
if i % 2 == 0:
pares.append(j)
# Con lo anterior conseguimos obtener todos los
# numeros pares en el rango de numeros enteros
# 0,1,2,3,4,5,6,7,8,9,10
print(pares)
[0, 2, 4, 6, 8, 10]
Podemos utilizar dentro de nuestras listas de comprensión condicionales:
# colocamos primero la parte del bucle for:
# pares = [i for i in range(1,11) . . .
# y despues el condicional:
# . . .if i % 2 == 0]
# De tal manera
pares = [i for i in range(0,11) if i % 2 == 0]
print(pares)
[0, 2, 4, 6, 8, 10]
De donde
De manera similar podemos crear una lista para agregar números impares
# lista para almacenar los numeros impares
impares = [i for i in range(0,11) if i % 2 != 0]
print(impares)
[1, 3, 5, 7, 9]
La idea de los diccionarios en Python coincide bastante con el concepto de diccionario de la "vida real". Podemos recordar que, en un diccionario, tenemos palabras claves, seguidas de su definición o valor correspondiente.
En Python los diccionarios estarán conformados por palabras claves, denominadas keys. Donde estas keys tendrán un valor asociado, denominado value. Así, la estructura de un diccionario se basa en la asociación key-value. Por ejemplo, podemos considerar un diccionario que sirva como agenda, de modo que podemos escribir:
key
: Lunes || value
: Estudiar programación en Pythonkey
: Martes || value
: Partidos de Futkey
: Miércoles || value
: Salida con amigoskey
: Jueves || value
: Estudiar álgebrakey
: Viernes || value
: Salida con amigosAhora, basándonos en la idea key-value podemos implementar un diccionario en Python, el cual, básicamente, posee la siguiente estructura:
<nombre asignado> = {key1: value1, key2: value2, key3: value3, ...}
Donde, tanto las llaves (keys), como los valores (values) pueden ser de distintos tipos de datos. Además, nota que, para definir un diccionario, ocupamos llaves {}
. Luego, utilizando la agenda que escribimos antes, declaremos nuestro primer diccionario:
# diccionario de la agenda de antes
agenda = {"Lunes": "Estudiar programación en Python", "Martes": "Partidos de Fut",
"Miércoles": "Salida con amigos", "Jueves": "Estudiar álgeba",
"Viernes": "Salida con amigos"}
# imprimimos el diccionario anterior
print(agenda)
print()
# tipo de dato de la variable agenda
print(type(agenda))
{'Lunes': 'Estudiar programación en Python', 'Martes': 'Partidos de Fut', 'Miércoles': 'Salida con amigos', 'Jueves': 'Estudiar álgeba', 'Viernes': 'Salida con amigos'} <class 'dict'>
Antes de continuar, mencionaremos que existe un módulo en Python con el cual las impresiones son más visuales para ciertas estructuras de datos. Así, ocuparemos el módulo pprint
de la librería pprint
para que la salida de nuestros diccionarios sea un poco más visual. Para ello:
# Importacion
# le damos el alias pp
from pprint import pprint as pp
# Imprimimos utilizando este modulo
# nuestro diccionario
pp(agenda)
{'Jueves': 'Estudiar álgeba', 'Lunes': 'Estudiar programación en Python', 'Martes': 'Partidos de Fut', 'Miércoles': 'Salida con amigos', 'Viernes': 'Salida con amigos'}
vemos de una manera más estructurada nuestra salida del diccionario agenda
. No obstante, el orden que nos muestra es un orden alfabético respecto a las cadenas de las keys. Para arreglar lo anterior agregamos el parámetro sort_dicts
y le asignamos el valor de False
para que la función pprint
no ordene las keys de dicha manera de nuestro diccionario, y así se muestre el mismo orden con el cual lo definimos
pp(agenda, sort_dicts = False)
{'Lunes': 'Estudiar programación en Python', 'Martes': 'Partidos de Fut', 'Miércoles': 'Salida con amigos', 'Jueves': 'Estudiar álgeba', 'Viernes': 'Salida con amigos'}
Podemos obtener también la longitud de un diccionario utilizando la función len()
# el cual nos arrojara el numero total de keys
# en nuestro diccionario
print(len(agenda))
5
De manera un poco distinta a las listas o tuplas, podemos acceder a los elementos de un diccionario. Para acceder a las keys de los diccionarios, ocupamos corchetes y dentro de ellos el nombre correspondiente a una de las keys de dicho diccionario, lo que se nos arrojará será el value asociado a dicha key.
Por ejemplo, podemos escribir agenda["Lunes"]
y la salida será el valor "Estudiar programación en Python"
. En efecto
# imprimimos el value asociado a la key "Lunes"
print(agenda["Lunes"])
print()
# imprimimos el value asociado a la key "Viernes"
print(agenda["Viernes"])
Estudiar programación en Python Salida con amigos
De manera totalmente análoga a lo anterior, podemos acceder a un valor de una key en específico utilizando el método get()
como sigue
# imprimimos el value asociado a la key "Lunes"
print(agenda.get("Lunes"))
print()
# imprimimos el value asociado a la key "Viernes"
print(agenda.get("Viernes"))
Estudiar programación en Python Salida con amigos
Podemos cambiar un value asociado a una key. Por ejemplo, podemos cambiar de "Estudiar programación en Python"
asociado a la key "Lunes"
, al valor "Estudiar programación en Java"
. Para ello:
# accedemos al valor de la llave "Lunes" --> agenda["Lunes"]
# asignamos un nuevo valor a esta llave:
agenda["Lunes"] = "Estudiar programación en Java"
# Imprimos el diccionario
pp(agenda, sort_dicts=False)
{'Lunes': 'Estudiar programación en Java', 'Martes': 'Partidos de Fut', 'Miércoles': 'Salida con amigos', 'Jueves': 'Estudiar álgeba', 'Viernes': 'Salida con amigos'}
print(agenda["Lunes"])
Estudiar programación en Java
Vemos que, justamente, el valor asociado al Lunes ha cambiado. De manera muy similar, podemos agregar nuevos key-value a nuestros diccionarios. Por ejemplo, podemos agregar:
key
: Sábado || value
: DescansarPara ello:
# agregamos un nuevo key-value a nuestra agenda:
# creamos una || le asignamos el
# nueva llave || valor descansar
agenda["Sábado"] = "Descansar"
# imprimimos nuestro diccionario
pp(agenda, sort_dicts=False)
{'Lunes': 'Estudiar programación en Java', 'Martes': 'Partidos de Fut', 'Miércoles': 'Salida con amigos', 'Jueves': 'Estudiar álgeba', 'Viernes': 'Salida con amigos', 'Sábado': 'Descansar'}
Vemos que se ha agregado la nueva información a nuestro diccionario agenda
. Podemos acceder a todas las keys de nuestro diccionario mediante un bucle for
:
# imprimimos todas las llaves
# de la agenda:
for _ in agenda:
print(_, end = " ")
Lunes Martes Miércoles Jueves Viernes Sábado
Para acceder a todas las keys y todos los values de nuestro diccionario utilizaremos el método item()
. Al emplear el método item()
sobre un diccionario, se genera una "colección" de tuplas, en las cuales se hace la correspondencia (key1, value1), (key2, value2), (key3, value3),...
(notemso que las primeras entradas de las tuplas corresponde a las keys y las segundas entradas a los values). Así, si escribimos agenda.items()
, lo que obtendremos será la "colección" de tuplas:
('Lunes', 'Estudiar programación en Java'), ('Martes', 'Partidos de Fut'),
('Miércoles', 'Salida con amigos'), ('Jueves', 'Estudiar álgeba'),
('Viernes', 'Salida con amigos'), ('Sábado', 'Descansar')
En efecto:
print(agenda.items())
dict_items([('Lunes', 'Estudiar programación en Java'), ('Martes', 'Partidos de Fut'), ('Miércoles', 'Salida con amigos'), ('Jueves', 'Estudiar álgeba'), ('Viernes', 'Salida con amigos'), ('Sábado', 'Descansar')])
De tal manera, podemos emplear un for
, teniendo ahora dos variables asociadas a este bucle (digamos i
y j
), sobre la "colección" agenda.items()
. Donde la i
tomará los valores de la primera entrada de las tuplas, es decir, la i
tomará las keys; asimismo, la j
tomará los values
Con base en todo lo anterior , podemos escribir un bucle for
como sigue:
for i, j in agenda.items():
print(f"Key: {i} --> Value: {j}")
# u otro ejemplo
print("-" * 60)
for i, j in agenda.items():
print(f"{i} || {j}")
Key: Lunes --> Value: Estudiar programación en Java Key: Martes --> Value: Partidos de Fut Key: Miércoles --> Value: Salida con amigos Key: Jueves --> Value: Estudiar álgeba Key: Viernes --> Value: Salida con amigos Key: Sábado --> Value: Descansar ------------------------------------------------------------ Lunes || Estudiar programación en Java Martes || Partidos de Fut Miércoles || Salida con amigos Jueves || Estudiar álgeba Viernes || Salida con amigos Sábado || Descansar
Podemos utilizar lo aprendido sobre los formatos para hacer algo como
# Podemos darle un poco mas de formato, algo
# asi como una tabla:
# declaramos una variable que almacene 40 guiones
guiones = "-" * 51
# Primer columna
print(f"|{guiones}|")
print("|{:^15}|{:^35}|".format("DÍA", "TAREA"))
print(f"|{guiones}|")
# iteramos
for i, j in agenda.items():
# alineamos al centro con ^
print("|{:^15}|{:^35}|".format(i, j))
print(f"|{guiones}|")
|---------------------------------------------------| | DÍA | TAREA | |---------------------------------------------------| | Lunes | Estudiar programación en Java | |---------------------------------------------------| | Martes | Partidos de Fut | |---------------------------------------------------| | Miércoles | Salida con amigos | |---------------------------------------------------| | Jueves | Estudiar álgeba | |---------------------------------------------------| | Viernes | Salida con amigos | |---------------------------------------------------| | Sábado | Descansar | |---------------------------------------------------|
Por otro lado, así como el método items()
nos arroja una "colección" de tuplas de la forma (key x, value x)
, donde $x=1,2,..$. Tenemos un método similar para extraer solamente o las keys o los values. Esto es, si ocupamos el método keys()
sobre un diccionario, obtenemos una "colección" de todas las keys de dicho diccionario. Por ejemplo
# para el diccionario agenda
print(agenda.keys())
dict_keys(['Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'])
Si ocupamos el método values()
sobre un diccionario, obtenemos una "colección" de todas los values de dicho diccionario. Por ejemplo
# para el diccionario agenda
print(agenda.values())
dict_values(['Estudiar programación en Java', 'Partidos de Fut', 'Salida con amigos', 'Estudiar álgeba', 'Salida con amigos', 'Descansar'])
Así, podemos iterar sobre éstos:
# para las llaves:
for i in agenda.keys():
print(f"Esto es una llave: {i}")
# o tambien denomiando a la variable
# del bucle de una manera mas concorde
# a lo que se esta haciendo
print("-" * 30)
for key in agenda.keys():
print(f"Esto es una llave: {key}")
Esto es una llave: Lunes Esto es una llave: Martes Esto es una llave: Miércoles Esto es una llave: Jueves Esto es una llave: Viernes Esto es una llave: Sábado ------------------------------ Esto es una llave: Lunes Esto es una llave: Martes Esto es una llave: Miércoles Esto es una llave: Jueves Esto es una llave: Viernes Esto es una llave: Sábado
# para los valores:
for value in agenda.values():
print(f"Esto es un valor: {value}")
Esto es un valor: Estudiar programación en Java Esto es un valor: Partidos de Fut Esto es un valor: Salida con amigos Esto es un valor: Estudiar álgeba Esto es un valor: Salida con amigos Esto es un valor: Descansar