Introducción a Listas, Diccionarios y Conjuntos

PythonPythonBeginner
Practicar Ahora

This tutorial is from open-source community. Access the source code

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

Esta sección aborda listas, diccionarios y conjuntos.

Resumen

Los programas a menudo tienen que trabajar con muchos objetos.

  • Un portafolio de acciones
  • Una tabla de precios de acciones

Hay tres opciones principales para utilizar.

  • Listas. Datos ordenados.
  • Diccionarios. Datos no ordenados.
  • Conjuntos. Colección no ordenada de elementos únicos.

Listas como Contenedores

Utilice una lista cuando importe el orden de los datos. Recuerde que las listas pueden contener cualquier tipo de objeto. Por ejemplo, una lista de tuplas.

portfolio = [
    ('GOOG', 100, 490.1),
    ('IBM', 50, 91.3),
    ('CAT', 150, 83.44)
]

portfolio[0]            ## ('GOOG', 100, 490.1)
portfolio[2]            ## ('CAT', 150, 83.44)

Construcción de listas

Construir una lista desde cero.

records = []  ## Lista vacía inicial

## Use.append() para agregar más elementos
records.append(('GOOG', 100, 490.10))
records.append(('IBM', 50, 91.3))
...

Un ejemplo al leer registros de un archivo.

records = []  ## Lista vacía inicial

with open('portfolio.csv', 'rt') as f:
    next(f) ## Saltar el encabezado
    for line in f:
        row = line.split(',')
        records.append((row[0], int(row[1]), float(row[2])))

Diccionarios como Contenedores

Los diccionarios son útiles si desea búsquedas aleatorias rápidas (por nombre de clave). Por ejemplo, un diccionario de precios de acciones:

prices = {
   'GOOG': 513.25,
   'CAT': 87.22,
   'IBM': 93.37,
   'MSFT': 44.12
}

Aquí hay algunas búsquedas simples:

>>> prices['IBM']
93.37
>>> prices['GOOG']
513.25
>>>

Construcción de Diccionarios

Ejemplo de construcción de un diccionario desde cero.

prices = {} ## Diccionario vacío inicial

## Insertar nuevos elementos
prices['GOOG'] = 513.25
prices['CAT'] = 87.22
prices['IBM'] = 93.37

Un ejemplo de llenado del diccionario a partir del contenido de un archivo.

prices = {} ## Diccionario vacío inicial

with open('prices.csv', 'rt') as f:
    for line in f:
        row = line.split(',')
        prices[row[0]] = float(row[1])

Nota: Si intenta esto con el archivo prices.csv, encontrará que casi funciona, pero hay una línea en blanco al final que hace que se detenga. Tendrá que encontrar alguna manera de modificar el código para tener en cuenta eso (ver Ejercicio 2.6).

Búsquedas en Diccionarios

Puedes probar la existencia de una clave.

if key in d:
    ## SI
else:
    ## NO

Puedes buscar un valor que puede no existir y proporcionar un valor predeterminado en caso de que no exista.

name = d.get(key, default)

Un ejemplo:

>>> prices.get('IBM', 0.0)
93.37
>>> prices.get('SCOX', 0.0)
0.0
>>>

Claves Compuestas

Casi cualquier tipo de valor puede usarse como clave de un diccionario en Python. La clave de un diccionario debe ser de un tipo inmutable. Por ejemplo, tuplas:

holidays = {
  (1, 1) : 'New Years',
  (3, 14) : 'Pi day',
  (9, 13) : "Programmer's day",
}

Luego, para acceder:

>>> holidays[3, 14]
'Pi day'
>>>

Ni una lista, ni un conjunto, ni otro diccionario pueden servir como clave de un diccionario, porque las listas y los diccionarios son mutables.

Conjuntos

Los conjuntos son colecciones de elementos únicos y no ordenados.

tech_stocks = { 'IBM','AAPL','MSFT' }
## Sintaxis alternativa
tech_stocks = set(['IBM', 'AAPL', 'MSFT'])

Los conjuntos son útiles para las pruebas de pertenencia.

>>> tech_stocks
set(['AAPL', 'IBM', 'MSFT'])
>>> 'IBM' in tech_stocks
True
>>> 'FB' in tech_stocks
False
>>>

Los conjuntos también son útiles para eliminar duplicados.

names = ['IBM', 'AAPL', 'GOOG', 'IBM', 'GOOG', 'YHOO']

unique = set(names)
## unique = set(['IBM', 'AAPL','GOOG','YHOO'])

Operaciones adicionales de conjuntos:

unique.add('CAT')        ## Agregar un elemento
unique.remove('YHOO')    ## Eliminar un elemento

s1 = { 'a', 'b', 'c'}
s2 = { 'c', 'd' }
s1 | s2                 ## Unión de conjuntos { 'a', 'b', 'c', 'd' }
s1 & s2                 ## Intersección de conjuntos { 'c' }
s1 - s2                 ## Diferencia de conjuntos { 'a', 'b' }

En estos ejercicios, empiezas a construir uno de los principales programas utilizados para el resto de este curso. Realiza tu trabajo en el archivo report.py.

Ejercicio 2.4: Una lista de tuplas

El archivo portfolio.csv contiene una lista de acciones en un portafolio. En el Ejercicio 1.30, escribiste una función portfolio_cost(filename) que leía este archivo y realizaba un cálculo simple.

Tu código debería haber sido algo así:

## pcost.py

import csv

def portfolio_cost(filename):
    '''Calcula el costo total (acciones*precio) de un archivo de portafolio'''
    total_cost = 0.0

    with open(filename, 'rt') as f:
        rows = csv.reader(f)
        headers = next(rows)
        for row in rows:
            nshares = int(row[1])
            price = float(row[2])
            total_cost += nshares * price
    return total_cost

Usando este código como guía aproximada, crea un nuevo archivo report.py. En ese archivo, define una función read_portfolio(filename) que abre un archivo de portafolio dado y lo lee en una lista de tuplas. Para hacer esto, vas a hacer algunos cambios menores al código anterior.

Primero, en lugar de definir total_cost = 0, crearás una variable que inicialmente se establece en una lista vacía. Por ejemplo:

portfolio = []

Luego, en lugar de sumar el costo, convertirás cada fila en una tupla exactamente como lo hiciste en el último ejercicio y la agregará a esta lista. Por ejemplo:

for row in rows:
    holding = (row[0], int(row[1]), float(row[2]))
    portfolio.append(holding)

Finalmente, devolverás la lista portfolio resultante.

Experimenta con tu función de forma interactiva (simplemente un recordatorio de que para hacer esto, primero debes ejecutar el programa report.py en el intérprete):

Consejo: Utiliza -i cuando ejecutes el archivo en la terminal

>>> portfolio = read_portfolio('/home/labex/project/portfolio.csv')
>>> portfolio
[('AA', 100, 32.2), ('IBM', 50, 91.1), ('CAT', 150, 83.44), ('MSFT', 200, 51.23),
    ('GE', 95, 40.37), ('MSFT', 50, 65.1), ('IBM', 100, 70.44)]
>>>
>>> portfolio[0]
('AA', 100, 32.2)
>>> portfolio[1]
('IBM', 50, 91.1)
>>> portfolio[1][1]
50
>>> total = 0.0
>>> for s in portfolio:
        total += s[1] * s[2]

>>> print(total)
44671.15
>>>

Esta lista de tuplas que has creado es muy similar a una matriz bidimensional. Por ejemplo, puedes acceder a una columna y fila específicas usando una búsqueda como portfolio[row][column] donde row y column son enteros.

Dicho esto, también puedes reescribir el último bucle for usando una declaración como esta:

>>> total = 0.0
>>> for name, shares, price in portfolio:
            total += shares*price

>>> print(total)
44671.15
>>>
✨ Revisar Solución y Practicar

Ejercicio 2.5: Lista de Diccionarios

Toma la función que escribiste en el Ejercicio 2.4 y modifícalo para representar cada acción en el portafolio con un diccionario en lugar de una tupla. En este diccionario, utiliza los nombres de campo "name", "shares" y "price" para representar las diferentes columnas en el archivo de entrada.

Experimenta con esta nueva función de la misma manera que lo hiciste en el Ejercicio 2.4.

>>> portfolio = read_portfolio('/home/labex/project/portfolio.csv')
>>> portfolio
[{'name': 'AA','shares': 100, 'price': 32.2}, {'name': 'IBM','shares': 50, 'price': 91.1},
    {'name': 'CAT','shares': 150, 'price': 83.44}, {'name': 'MSFT','shares': 200, 'price': 51.23},
    {'name': 'GE','shares': 95, 'price': 40.37}, {'name': 'MSFT','shares': 50, 'price': 65.1},
    {'name': 'IBM','shares': 100, 'price': 70.44}]
>>> portfolio[0]
{'name': 'AA','shares': 100, 'price': 32.2}
>>> portfolio[1]
{'name': 'IBM','shares': 50, 'price': 91.1}
>>> portfolio[1]['shares']
50
>>> total = 0.0
>>> for s in portfolio:
        total += s['shares']*s['price']

>>> print(total)
44671.15
>>>

Aquí, notarás que los diferentes campos para cada entrada se acceden por nombres de clave en lugar de números de columna numéricos. Esto suele ser preferible porque el código resultante es más fácil de leer más adelante.

Ver grandes diccionarios y listas puede ser desordenado. Para limpiar la salida para la depuración, considera usar la función pprint.

>>> from pprint import pprint
>>> pprint(portfolio)
[{'name': 'AA', 'price': 32.2,'shares': 100},
    {'name': 'IBM', 'price': 91.1,'shares': 50},
    {'name': 'CAT', 'price': 83.44,'shares': 150},
    {'name': 'MSFT', 'price': 51.23,'shares': 200},
    {'name': 'GE', 'price': 40.37,'shares': 95},
    {'name': 'MSFT', 'price': 65.1,'shares': 50},
    {'name': 'IBM', 'price': 70.44,'shares': 100}]
>>>
✨ Revisar Solución y Practicar

Ejercicio 2.6: Diccionarios como contenedor

Un diccionario es una forma útil de mantener un registro de elementos cuando se desea buscar elementos utilizando un índice diferente de un entero. En la shell de Python, intenta jugar con un diccionario:

>>> prices = { }
>>> prices['IBM'] = 92.45
>>> prices['MSFT'] = 45.12
>>> prices
... mira el resultado...
>>> prices['IBM']
92.45
>>> prices['AAPL']
... mira el resultado...
>>> 'AAPL' in prices
False
>>>

El archivo prices.csv contiene una serie de líneas con los precios de las acciones. El archivo se parece a esto:

"AA",9.22
"AXP",24.85
"BA",44.85
"BAC",11.27
"C",3.72
...

Escribe una función read_prices(filename) que lea un conjunto de precios como este en un diccionario donde las claves del diccionario son los nombres de las acciones y los valores en el diccionario son los precios de las acciones.

Para hacer esto, comienza con un diccionario vacío y comienza a insertar valores en él exactamente como lo hiciste anteriormente. Sin embargo, ahora estás leyendo los valores de un archivo.

Utilizaremos esta estructura de datos para buscar rápidamente el precio de un nombre de acción dado.

Unos pocos consejos que necesitarás para esta parte. Primero, asegúrate de usar el módulo csv como lo hiciste antes: no es necesario reinventar la rueda aquí.

>>> import csv
>>> f = open('/home/labex/project/prices.csv', 'r')
>>> rows = csv.reader(f)
>>> for row in rows:
        print(row)


['AA', '9.22']
['AXP', '24.85']
...
[]
>>>

La otra pequeña complicación es que el archivo prices.csv puede tener algunas líneas en blanco. Observa cómo la última fila de datos arriba es una lista vacía, lo que significa que no había datos en esa línea.

Es posible que esto cause que tu programa se detenga con una excepción. Utiliza las declaraciones try y except para capturar esto adecuadamente. Pensamiento: ¿sería mejor protegerse contra datos incorrectos con una declaración if en lugar de eso?

Una vez que hayas escrito tu función read_prices(), pruébalo de forma interactiva para asegurarte de que funcione:

>>> prices = read_prices('/home/labex/project/prices.csv')
>>> prices['IBM']
106.28
>>> prices['MSFT']
20.89
>>>
✨ Revisar Solución y Practicar

Ejercicio 2.7: Saber si puedes jubilarte

Une todo este trabajo agregando algunas declaraciones adicionales a tu programa report.py que calcula la ganancia/perdida. Estas declaraciones deben tomar la lista de acciones del Ejercicio 2.5 y el diccionario de precios del Ejercicio 2.6 y calcular el valor actual del portafolio junto con la ganancia/perdida.

✨ Revisar Solución y Practicar

Resumen

¡Felicidades! Has completado el laboratorio de Contenedores. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.