Curso de introducción a la programación con Python¶

    Autor: Luis Fernando Apáez Álvarez
    -Curso PyM-
    Clase 5: Colecciones I
    Fecha: 12 de Agosto del 2022

Contenido¶

  • Listas
  • Tuplas
  • Listas de comprensión
  • Diccionarios

Introducción¶

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

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

In [3]:
# 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

In [9]:
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:

In [13]:
# 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

In [14]:
# 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

In [15]:
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:

In [18]:
# 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

In [19]:
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:

In [20]:
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:

In [21]:
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:

In [23]:
print(lista_mix.index(False))

# o tambien, hallemos el indice del elemento :D
print()
print(lista_mix.index(":D"))
3

4

Método append()¶

Gracias a este método podemos agregar elementos nuevos a nuestras listas. Por ejemplo

In [24]:
# 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

In [25]:
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

In [26]:
# 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

In [28]:
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.

In [29]:
# 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

In [41]:
lista5 = [1, 3.1416, "Hola"]

# el elemento 1 esta en la lista5?
print(1 in lista5)
True
In [42]:
# 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

Tuplas ¶

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:

In [43]:
# 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

In [8]:
# 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:

In [9]:
# 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

In [10]:
# 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

In [11]:
# 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

In [46]:
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

In [47]:
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:

Listas de comprensión ¶

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:

In [48]:
# 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)

Capturas4.PNG

Podemos ver otro ejemplo, donde ahora agregaremos los cuadrados de los números 1,2,3,4 y 5 en una nueva lista:

In [49]:
# 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:

Capturas6.PNG

Otro ejemplo. Podemos agregar todos los caracteres de una cdena de texto dada, en una lista utilizando el concepto de listas de comprensión :

In [52]:
# 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

In [54]:
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:

In [55]:
# 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:

In [57]:
# 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

Capturas7.PNG

De manera similar podemos crear una lista para agregar números impares

In [59]:
# 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]

Diccionarios ¶

Programamos%20%283%29.png

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 Python
  • key: Martes || value: Partidos de Fut
  • key: Miércoles || value: Salida con amigos
  • key: Jueves || value: Estudiar álgebra
  • key: Viernes || value: Salida con amigos

Ahora, 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:

In [2]:
# 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:

In [5]:
# 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

In [6]:
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()

In [7]:
# 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

In [14]:
# 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

In [15]:
# 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:

In [16]:
# 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'}
In [17]:
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: Descansar

Para ello:

In [18]:
# 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:

In [21]:
# 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:

In [23]:
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

Capturad1.PNG

Con base en todo lo anterior , podemos escribir un bucle for como sigue:

In [53]:
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

In [55]:
# 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

In [57]:
# 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

In [58]:
# 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:

In [59]:
# 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
In [60]:
# 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