Retrouver des valeurs par leur nom
Un dictionnaire (dict) associe des clés à des valeurs : {"AAPL": 184.5, "MSFT": 410.2}. Là où une liste trouve un élément par sa position, un dictionnaire le trouve par sa clé, et la recherche reste rapide quel que soit le nombre d'entrées. prices["AAPL"] lit une valeur, prices["TSLA"] = 251.0 ajoute une entrée ou remplace l'existante, et "AAPL" in prices demande si une clé existe. Lire une clé absente avec des crochets lève une 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 : une clé absente n'est pas une erreur
prices.get("GOOG", 0.0) renvoie la valeur, ou le défaut donné si la clé manque (None si vous n'en donnez pas), et ne lève jamais d'erreur. Cela facilite un compteur : counts[symbol] = counts.get(symbol, 0) + 1 part de 0 pour un nouveau symbole et ajoute un à chaque occurrence. Utilisez [] quand une clé absente serait un bogue dont vous voulez être averti, et get quand l'absence est normale.
# 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}Parcourir un dictionnaire
Un simple for key in prices parcourt les clés. Utilisez prices.values() pour les valeurs et prices.items() pour les paires (clé, valeur), que l'on déballe dans la boucle : for symbol, price in prices.items(). Les dictionnaires se souviennent de l'ordre dans lequel les clés ont été ajoutées. N'ajoutez ni ne retirez de clés pendant que vous parcourez le même dictionnaire ; parcourez une copie ou construisez un nouveau dictionnaire.
# 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.0Retirer, fusionner et copier
prices.pop("AAPL", None) retire une clé et renvoie sa valeur (le défaut si elle manquait) ; del prices["AAPL"] la retire et lève KeyError si elle est absente. a.update(b) copie les entrées de b dans a, qui est modifié ; {**a, **b} ou a | b construit un nouveau dictionnaire où b l'emporte sur les clés communes. Comme pour les listes, copy = prices n'est qu'un second nom : utilisez dict(prices) ou prices.copy() pour une vraie copie.
# 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'}Ce qui peut servir de clé
Une clé doit être hachable, ce qui signifie en pratique qu'elle ne peut pas changer : chaînes, nombres et tuples de ceux-ci conviennent, pas les listes ni les dictionnaires. Les tuples font de bonnes clés composées, par exemple (symbol, venue). Les valeurs peuvent être n'importe quoi, y compris une autre liste ou un autre dictionnaire. Une même clé ne peut apparaître qu'une fois : lui assigner à nouveau remplace l'ancienne valeur.
# 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] dit « cette clé doit être là » et échoue bruyamment si ce n'est pas le cas. prices.get(symbol, default) dit « l'absence est acceptable ». Cacher un vrai bogue derrière un défaut est aussi mauvais que planter sur un cas normal : décidez ce que vous voulez dire. Les labs vérifient aussi que les dictionnaires reçus ne sont pas modifiés.d[key],d[key] = value,key in d: lire, écrire, tester une clé.d.get(key, default): une recherche sûre ;d.items(): des paires à parcourir.d.pop(key, default),del d[key],d.update(other),{**a, **b}: retirer et fusionner.
À suivre : les ensembles, des collections de valeurs uniques avec des tests d'appartenance rapides et une arithmétique ensembliste élégante.
Lab : ce qui est noté
- Garder le prix le plus récent par symbole avec
latest_prices25 pts - Compter la fréquence de chaque symbole avec
count_symbols25 pts - Valoriser un portefeuille à partir de deux dictionnaires avec
portfolio_value25 pts - Combiner deux livres de positions avec
merge_positions25 pts