Buscar cosas por nombre
Un diccionario (dict) asocia claves con valores: {"AAPL": 184.5, "MSFT": 410.2}. Donde una lista encuentra un elemento por posición, un diccionario lo encuentra por clave, y la búsqueda sigue siendo rápida sea cual sea el número de entradas. prices["AAPL"] lee un valor, prices["TSLA"] = 251.0 añade una entrada o reemplaza la existente, y "AAPL" in prices pregunta si existe una clave. Leer una clave ausente con corchetes lanza un KeyError.
prices = {"AAPL": 184.5, "MSFT": 410.2}
# Read, add and replace
print(prices["AAPL"]) # 184.5
prices["TSLA"] = 251.0
prices["AAPL"] = 185.0
print(prices) # {'AAPL': 185.0, 'MSFT': 410.2, 'TSLA': 251.0}
# in tests the keys; a missing key raises KeyError
print("MSFT" in prices, "GOOG" in prices) # True False
try:
prices["GOOG"]
except KeyError as error:
print("no such key:", error)get: una clave ausente no es un error
prices.get("GOOG", 0.0) devuelve el valor, o el valor por defecto que des si falta la clave (None si no das ninguno), y nunca lanza error. Eso facilita un contador: counts[symbol] = counts.get(symbol, 0) + 1 parte de 0 para un símbolo nuevo y suma uno por cada aparición. Usa [] cuando una clave ausente sería un error del que quieres enterarte, y get cuando la ausencia es normal.
# get() with a default never raises
prices = {"AAPL": 184.5}
print(prices.get("AAPL", 0.0)) # 184.5
print(prices.get("GOOG", 0.0)) # 0.0
print(prices.get("GOOG")) # None
# Counting with get
counts = {}
for symbol in ["AAPL", "MSFT", "AAPL", "AAPL"]:
counts[symbol] = counts.get(symbol, 0) + 1
print(counts) # {'AAPL': 3, 'MSFT': 1}Recorrer un diccionario
Un simple for key in prices recorre las claves. Usa prices.values() para los valores y prices.items() para pares (clave, valor), que se desempaquetan en el bucle: for symbol, price in prices.items(). Los diccionarios recuerdan el orden en que se añadieron las claves. No añadas ni quites claves mientras recorres el mismo diccionario; recorre una copia o construye uno nuevo.
# keys(), values() and items()
positions = {"AAPL": 200, "MSFT": 50, "GOOG": 0}
prices = {"AAPL": 184.5, "MSFT": 410.2}
for symbol in positions:
print(symbol, end=" ") # AAPL MSFT GOOG
print()
total = 0.0
for symbol, quantity in positions.items():
total += quantity * prices.get(symbol, 0.0)
print(round(total, 2)) # 57410.0Quitar, combinar y copiar
prices.pop("AAPL", None) quita una clave y devuelve su valor (el valor por defecto si faltaba); del prices["AAPL"] la quita y lanza KeyError si no está. a.update(b) copia las entradas de b en a, modificándolo; {**a, **b} o a | b construye un diccionario nuevo donde b gana en las claves comunes. Como con las listas, copy = prices es solo un segundo nombre: usa dict(prices) o prices.copy() para una copia real.
# Removing and merging
book = {"AAPL": 200, "MSFT": 50}
sold = book.pop("MSFT", 0)
print(sold, book) # 50 {'AAPL': 200}
# {**a, **b} builds a new dict; b wins on shared keys
defaults = {"fee": 0.001, "currency": "USD"}
custom = {"fee": 0.0005}
settings = {**defaults, **custom}
print(settings) # {'fee': 0.0005, 'currency': 'USD'}
print(defaults) # unchanged: {'fee': 0.001, 'currency': 'USD'}Qué puede ser una clave
Una clave debe ser hashable, lo que en la práctica significa que no puede cambiar: cadenas, números y tuplas de ellos sirven; listas y diccionarios no. Las tuplas son buenas claves compuestas, por ejemplo (symbol, venue). Los valores pueden ser cualquier cosa, incluida otra lista u otro diccionario. Una misma clave solo puede aparecer una vez, así que asignarle de nuevo reemplaza el valor anterior.
# A tuple as a compound key, a list as a value
best = {("AAPL", "NYSE"): 184.6, ("AAPL", "ARCA"): 184.5}
print(best[("AAPL", "ARCA")]) # 184.5
fills = {"AAPL": [100, 250], "MSFT": [75]}
fills["AAPL"].append(40)
print(fills) # {'AAPL': [100, 250, 40], 'MSFT': [75]}
# A list cannot be a key
try:
{["AAPL"]: 1}
except TypeError as error:
print("not hashable:", error)prices[symbol] dice «esta clave debe estar» y falla ruidosamente si no está. prices.get(symbol, default) dice «que falte está bien». Ocultar un error real tras un valor por defecto es tan malo como fallar en un caso normal, así que decide cuál quieres decir. Los labs también comprueban que los diccionarios recibidos no cambian.d[key],d[key] = value,key in d: leer, escribir, probar una clave.d.get(key, default): una búsqueda segura;d.items(): pares para recorrer.d.pop(key, default),del d[key],d.update(other),{**a, **b}: quitar y combinar.
A continuación: conjuntos, colecciones de valores únicos con pruebas de pertenencia rápidas y una aritmética de conjuntos elegante.
Lab: qué se califica
- Guardar el precio más reciente por símbolo con
latest_prices25 pts - Contar cuántas veces aparece cada símbolo con
count_symbols25 pts - Valorar una cartera con dos diccionarios usando
portfolio_value25 pts - Combinar dos libros de posiciones con
merge_positions25 pts