Un dictionnaire prend plus de place qu'une liste
Exercice supplémentaire · niveau 3 (difficile) · NSI (première), chapitre 5 — Les dictionnaires · Aux frontières du programme
Énoncé
Un dictionnaire prend plus de place qu'une liste. Mesurer avec sys.getsizeof la taille de dictionnaires de , , , et entrées. La croissance est-elle régulière ?
Corrigé
import sys
for n in [0, 5, 10, 100, 1000]:
print(n, sys.getsizeof({i: i for i in range(n)}))
# 0 64 5 224 10 352 100 4688 1000 36952
La croissance se fait par paliers, pas continûment. La table interne est agrandie d'un coup quand elle se remplit trop, puis ne bouge plus jusqu'au palier suivant : c'est pourquoi et entrées coûtent et octets, sans proportionnalité. Le dictionnaire garde délibérément de la place vide — c'est ce qui limite les collisions, donc ce qui maintient l'accès rapide.
Le prix de la rapidité.
assert sys.getsizeof(list(range(1000))) == 8056
assert sys.getsizeof({i: i for i in range(1000)}) == 36952
Environ quatre fois et demie plus de mémoire pour mille éléments. C'est un arbitrage, comme il y en aura beaucoup en terminale : on paie de la place pour gagner du temps. Sur mille éléments, cela ne se discute pas ; sur cent millions, le choix redevient une vraie question.
Une limite de la mesure. sys.getsizeof ne compte que la structure elle-même, pas les objets qu'elle référence : un dictionnaire de mille longues chaînes annonce la même taille qu'un dictionnaire de mille petits entiers. La mémoire réellement occupée est bien plus grande — ce que l'outil mesure et ce qu'on croit mesurer ne coïncident pas toujours.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.