En Python, une collection est un objet qui contient un groupe dâĂ©lĂ©ments et permet de les manipuler comme une unitĂ© unique.
Les collections supportent généralement :
- lâitĂ©ration (
for item in collection) - les tests dâappartenance (
x in collection) - la détermination de la longueur (
len(collection)) - lâaccĂšs par index ou clĂ© (si ordonnĂ© ou associatif)
Python nâa pas dâ« interface collection » stricte, mais suit des protocoles informels. Si un objet implĂ©mente
__iter__,__len__,__contains__, il peut ĂȘtre considĂ©rĂ© comme une collection.
- Ce qui NâEST PAS une collection
- Collections intégrées
- Collections étendues de la bibliothÚque standard
- Autres types similaires aux collections
- 1. Listes â
list - 2. Dictionnaires â
dict - 3. Tuples â
tuple - 4. SimpleNamespace
- 5. Ensembles â
set - 6. Ensembles immuables â
frozenset - 7. namedtuple â tuples nommĂ©s
- 8. deque â file double
- 9. Counter â compteur dâĂ©lĂ©ments
- 10. defaultdict â dictionnaire avec valeurs par dĂ©faut
- 11. dataclass â classes de donnĂ©es
- 12. UserList â listes personnalisĂ©es
- 13. UserDict â dictionnaires personnalisĂ©s
- đ Comparaison mĂ©moire et performance
- 1. Mémoire :
listvstuplevsarray.array - 2. Vitesse dâaccĂšs :
listvstuplevsarray.array - 3. Mémoire :
dictvsSimpleNamespacevsdataclass - 4. Optimisation mémoire :
dataclassavec__slots__ - 5. Vitesse de recherche :
listvsset - 6. Mémoire :
setvsfrozenset - 7. Vitesse dâajout :
list.appendvsdeque.appendvsdeque.appendleft
- 1. Mémoire :
- đ§ Recommandations de performance
- đ Comparaison des collections
- đĄ Quand utiliser quoi ?
Ce qui NâEST PAS une collection
Les types suivants ne sont pas des collections, car ils ne contiennent pas de groupes dâĂ©lĂ©ments :
int,float,boolâ valeurs scalairesNoneâ absence de valeur- fonctions, modules, classes â ce sont des objets, mais pas des conteneurs de donnĂ©es (sauf sâils contiennent
__dict__)
Collections intégrées
Disponibles sans import :
| Type | Description |
|---|---|
list | Séquence ordonnée, mutable. |
tuple | Séquence ordonnée, immuable. |
dict | Mappage clé-valeur ordonné (depuis Python 3.7). |
set | Collection non ordonnĂ©e dâĂ©lĂ©ments uniques. |
frozenset | Version immuable de set. |
Collections étendues de la bibliothÚque standard
| Type | Module | Utilité |
|---|---|---|
SimpleNamespace | types | Objet avec attributs dynamiques (alternative au dict avec accĂšs par .). |
namedtuple | collections | Tuple immuable avec champs nommés. |
deque | collections | File doublement terminĂ©e â efficace pour ajouts/retraits aux deux extrĂ©mitĂ©s. |
Counter | collections | Sous-classe de dict pour compter les objets hachables. |
defaultdict | collections | Dictionnaire avec valeurs par défaut pour les clés manquantes. |
dataclass | dataclasses | GénÚre automatiquement __init__, __repr__, __eq__, etc. |
UserList | collections | Classe de base pour objets de type liste personnalisés. |
UserDict | collections | Classe de base pour objets de type dictionnaire personnalisés. |
Autres types similaires aux collections
Bien quâon ne les appelle pas toujours « collections », ces types reprĂ©sentent ou stockent aussi des groupes de donnĂ©es.
1. str â chaĂźne de caractĂšres
Séquence ordonnée, immuable de caractÚres.
s = "Python"
print(len(s)) # â 6
print(s[0]) # â P
print('y' in s) # â True
print(list(s)) # â ['P', 'y', 't', 'h', 'o', 'n']
2. bytes, bytearray
bytesâ sĂ©quence immuable dâoctets.bytearrayâ version mutable.
b = b"bonjour"
print(b[0]) # â 98
print(len(b)) # â 7
ba = bytearray(b"bonjour")
ba[0] = 72
print(ba) # â bytearray(b'Hello')
3. range
Séquence numérique paresseuse, ordonnée. Ne stocke pas les éléments en mémoire.
r = range(3)
print(list(r)) # â [0, 1, 2]
print(1 in r) # â True
print(r[2]) # â 2
4. array.array
Stocke des données numériques homogÚnes de façon compacte (comme en C).
from array import array
arr = array('i', [1, 2, 3]) # 'i' = entier signé
print(arr) # â array('i', [1, 2, 3])
5. Générateurs et itérateurs
Ne stockent pas les donnĂ©es â les gĂ©nĂšrent Ă la demande. Ne supportent pas len() ni lâindexation.
gen = (x * 2 for x in range(3))
print(list(gen)) # â [0, 2, 4]
# len(gen) â TypeError
6. ChainMap (de collections)
Regroupe plusieurs dictionnaires en une seule vue â la recherche parcourt les maps dans lâordre.
from collections import ChainMap
d1 = {'a': 1}
d2 = {'b': 2}
cm = ChainMap(d1, d2)
print(cm['a']) # â 1
print(cm['b']) # â 2
7. OrderedDict (de collections)
Dictionnaire qui conserve lâordre dâinsertion. Pertinent pour Python < 3.7.
from collections import OrderedDict
od = OrderedDict([('a', 1), ('b', 2)])
print(od) # â OrderedDict([('a', 1), ('b', 2)])
8. enum.Enum, enum.Flag
Collections de constantes nommées.
from enum import Enum
class Couleur(Enum):
ROUGE = 1
VERT = 2
print(list(Couleur)) # â [<Couleur.ROUGE: 1>, <Couleur.VERT: 2>]
9. typing.NamedTuple, typing.TypedDict
Enveloppes typées autour de namedtuple et dict.
from typing import NamedTuple, TypedDict
class Personne(NamedTuple):
nom: str
age: int
p = Personne("Alice", 25)
class Film(TypedDict):
titre: str
annee: int
m: Film = {"titre": "Matrix", "annee": 1999}
10. heapq, bisect â outils, pas collections
Travaillent avec des collections, mais nâen sont pas :
heapqâ algorithme de file de prioritĂ© via listes.bisectâ maintient lâordre triĂ© dans les listes.
1. Listes â list
Collection ordonnée, mutable. Les éléments peuvent se répéter, tous types autorisés.
UtilisĂ©e quand on a besoin dâune sĂ©quence flexible : ajouter, supprimer, modifier des Ă©lĂ©ments.
Création : []
jean_list = ["Jean", "Paris", 30, "ingénieur"]
print(f"Création liste : {jean_list}")
# â CrĂ©ation liste : ['Jean', 'Paris', 30, 'ingĂ©nieur']
print(f"ĂlĂ©ment Ă lâindex 0 : {jean_list[0]}")
# â ĂlĂ©ment Ă lâindex 0 : Jean
jean_list[2] = 31
print(f"AprĂšs modification : {jean_list}")
# â AprĂšs modification : ['Jean', 'Paris', 31, 'ingĂ©nieur']
jean_list.append("marié")
print(f"AprĂšs append : {jean_list}")
# â AprĂšs append : ['Jean', 'Paris', 31, 'ingĂ©nieur', 'mariĂ©']
jean_list.insert(1, "France")
print(f"AprĂšs insert : {jean_list}")
# â AprĂšs insert : ['Jean', 'France', 'Paris', 31, 'ingĂ©nieur', 'mariĂ©']
jean_list.remove("ingénieur")
print(f"AprĂšs remove par valeur : {jean_list}")
# â AprĂšs remove par valeur : ['Jean', 'France', 'Paris', 31, 'mariĂ©']
del jean_list[2]
print(f"AprĂšs suppression par index : {jean_list}")
# â AprĂšs suppression par index : ['Jean', 'France', 31, 'mariĂ©']
jean_list.extend(["loisirs", "pĂȘche"])
print(f"AprĂšs extend : {jean_list}")
# â AprĂšs extend : ['Jean', 'France', 31, 'mariĂ©', 'loisirs', 'pĂȘche']
jean_list.pop()
print(f"AprĂšs pop : {jean_list}")
# â AprĂšs pop : ['Jean', 'France', 31, 'mariĂ©', 'loisirs']
2. Dictionnaires â dict
Collection de paires clĂ© â valeur. Les clĂ©s doivent ĂȘtre hachables. Depuis Python 3.7, lâordre dâinsertion est conservĂ©.
Utile pour les données structurées : profils, configs, JSON.
Création : {}
alice_dict = {"nom": "Alice", "age": 25, "ville": "Lyon", "profession": "artiste"}
print(f"Création dict : {alice_dict}")
# â CrĂ©ation dict : {'nom': 'Alice', 'age': 25, 'ville': 'Lyon', 'profession': 'artiste'}
print(f"Valeur pour clé 'nom' : {alice_dict['nom']}")
# â Valeur pour clĂ© 'nom' : Alice
alice_dict["age"] = 26
print(f"AprĂšs mise Ă jour : {alice_dict}")
# â AprĂšs mise Ă jour : {'nom': 'Alice', 'age': 26, 'ville': 'Lyon', 'profession': 'artiste'}
alice_dict["hobby"] = "peinture"
print(f"Ajout paire : {alice_dict}")
# â Ajout paire : {'nom': 'Alice', 'age': 26, 'ville': 'Lyon', 'profession': 'artiste', 'hobby': 'peinture'}
del alice_dict["ville"]
print(f"AprĂšs suppression paire : {alice_dict}")
# â AprĂšs suppression paire : {'nom': 'Alice', 'age': 26, 'profession': 'artiste', 'hobby': 'peinture'}
hobby = alice_dict.pop("hobby")
print(f"AprĂšs pop : {alice_dict}, valeur : {hobby}")
# â AprĂšs pop : {'nom': 'Alice', 'age': 26, 'profession': 'artiste'}, valeur : peinture
print(f"Clé 'nom' existe : {'nom' in alice_dict}")
# â ClĂ© 'nom' existe : True
3. Tuples â tuple
Collection ordonnée, immuable. Adaptée aux données fixes.
UtilisĂ©e quand lâimmuabilitĂ© est importante : coordonnĂ©es, paramĂštres, valeurs de retour.
Création : ()
jean_tuple = ("Jean", "Paris", 30, "ingénieur")
print(f"Création tuple : {jean_tuple}")
# â CrĂ©ation tuple : ('Jean', 'Paris', 30, 'ingĂ©nieur')
print(f"ĂlĂ©ment Ă lâindex 2 : {jean_tuple[2]}")
# â ĂlĂ©ment Ă lâindex 2 : 30
# jean_tuple[0] = "Pierre" â TypeError
# jean_tuple.append("quelque chose") â AttributeError
- Les tuples consomment moins de mémoire et sont plus rapides que les listes.
- IdĂ©al quand la mutabilitĂ© nâest pas nĂ©cessaire.
4. SimpleNamespace
Classe simple de types pour créer des objets avec attributs dynamiques. AccÚs via la notation pointée (obj.attr).
Utile quand on veut la syntaxe obj.nom sans définir une classe complÚte.
from types import SimpleNamespace
alice_ns = SimpleNamespace(nom="Alice", age=25, ville="Lyon")
print(f"Objet : {alice_ns}")
# â Objet : namespace(nom='Alice', age=25, ville='Lyon')
print(f"Nom : {alice_ns.nom}")
# â Nom : Alice
alice_ns.age = 26
print(f"AprĂšs mise Ă jour : {alice_ns}")
# â AprĂšs mise Ă jour : namespace(nom='Alice', age=26, ville='Lyon')
alice_ns.profession = "artiste"
print(f"Avec nouvel attribut : {alice_ns}")
# â Avec nouvel attribut : namespace(nom='Alice', age=26, ville='Lyon', profession='artiste')
del alice_ns.ville
print(f"AprĂšs suppression : {alice_ns}")
# â AprĂšs suppression : namespace(nom='Alice', age=26, profession='artiste')
setattr(alice_ns, "hobby", "peinture")
print(f"Via setattr : {alice_ns}")
# â Via setattr : namespace(nom='Alice', age=26, profession='artiste', hobby='peinture')
delattr(alice_ns, "hobby")
print(f"Via delattr : {alice_ns}")
# â Via delattr : namespace(nom='Alice', age=26, profession='artiste')
- Alternative au dict quand
obj.nomest prĂ©fĂ©rable Ăobj['nom'].
5. Ensembles â set
Collection non ordonnĂ©e dâĂ©lĂ©ments uniques. Supporte les opĂ©rations ensemblistes : union, intersection, diffĂ©rence.
UtilisĂ©e pour supprimer les doublons et tester lâappartenance.
Création : {} ou set()
nombres = {1, 2, 3, 3, 2, 1}
print(f"Ensemble : {nombres}")
# â Ensemble : {1, 2, 3}
nombres.add(4)
print(f"AprĂšs ajout : {nombres}")
# â AprĂšs ajout : {1, 2, 3, 4}
nombres.remove(2)
print(f"AprĂšs suppression : {nombres}")
# â AprĂšs suppression : {1, 3, 4}
autre = {3, 4, 5}
print(f"Union : {nombres | autre}")
# â Union : {1, 3, 4, 5}
print(f"Intersection : {nombres & autre}")
# â Intersection : {3, 4}
print(f"Différence : {nombres - autre}")
# â DiffĂ©rence : {1}
6. Ensembles immuables â frozenset
Version immuable de set. Peut ĂȘtre utilisĂ© comme clĂ© de dict ou Ă©lĂ©ment dâun autre ensemble.
frozen = frozenset([1, 2, 3, 2])
print(f"frozenset : {frozen}")
# â frozenset : frozenset({1, 2, 3})
autre = frozenset([3, 4])
print(f"Intersection : {frozen & autre}")
# â Intersection : frozenset({3})
print(f"Union : {frozen | autre}")
# â Union : frozenset({1, 2, 3, 4})
# frozen.add(5) â AttributeError
7. namedtuple â tuples nommĂ©s
Structure immuable avec accĂšs par nom de champ. Plus lisible que les tuples classiques.
from collections import namedtuple
Personne = namedtuple("Personne", ["nom", "age", "ville"])
alice = Personne("Alice", 25, "Lyon")
print(f"Objet : {alice}")
# â Objet : Personne(nom='Alice', age=25, ville='Lyon')
print(f"Nom : {alice.nom}")
# â Nom : Alice
print(f"Ăge : {alice[1]}")
# â Ăge : 25
# alice.age = 26 â AttributeError
alice_new = alice._replace(age=26)
print(f"Copie modifiée : {alice_new}")
# â Copie modifiĂ©e : Personne(nom='Alice', age=26, ville='Lyon')
- IdĂ©al pour les enregistrements : points, utilisateurs, configs â quand lâimmuabilitĂ© et la lisibilitĂ© comptent.
8. deque â file double
Optimisée pour les ajouts/retraits rapides aux deux extrémités. Plus efficace que list pour appendleft, popleft.
from collections import deque
d = deque([1, 2, 3])
print(f"deque initial : {d}")
# â deque initial : deque([1, 2, 3])
d.appendleft(0)
print(f"AprĂšs appendleft : {d}")
# â AprĂšs appendleft : deque([0, 1, 2, 3])
d.append(4)
print(f"AprĂšs append : {d}")
# â AprĂšs append : deque([0, 1, 2, 3, 4])
gauche = d.popleft()
print(f"AprĂšs popleft : {gauche}, restant : {d}")
# â AprĂšs popleft : 0, restant : deque([1, 2, 3, 4])
droite = d.pop()
print(f"AprĂšs pop : {droite}, restant : {d}")
# â AprĂšs pop : 4, restant : deque([1, 2, 3])
- UtilisĂ© dans les algorithmes : BFS, caches LRU, tampons â quand les opĂ©rations aux extrĂ©mitĂ©s doivent ĂȘtre rapides.
9. Counter â compteur dâĂ©lĂ©ments
Compte la frĂ©quence des Ă©lĂ©ments dans un itĂ©rable. Utile pour les statistiques et lâanalyse.
from collections import Counter
texte = "abracadabra"
c = Counter(texte)
print(f"Comptage lettres : {c}")
# â Comptage lettres : Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
print(f"Fréquence de 'a' : {c['a']}")
# â FrĂ©quence de 'a' : 5
print(f"Top 3 : {c.most_common(3)}")
# â Top 3 : [('a', 5), ('b', 2), ('r', 2)]
c2 = Counter("bukva")
c.update(c2)
print(f"AprĂšs update : {c}")
# â AprĂšs update : Counter({'a': 6, 'b': 3, 'r': 2, 'c': 1, 'd': 1, 'u': 1, 'k': 1, 'v': 1})
- Utile pour lâanalyse de texte, logs, votes â partout oĂč il faut compter « ce qui apparaĂźt le plus souvent ».
10. defaultdict â dictionnaire avec valeurs par dĂ©faut
CrĂ©e automatiquement des valeurs par dĂ©faut pour les clĂ©s manquantes. Ălimine les vĂ©rifications if key in dict.
from collections import defaultdict
dd_list = defaultdict(list)
dd_list["fruits"].append("pomme")
dd_list["fruits"].append("banane")
print(f"Liste : {dict(dd_list)}")
# â Liste : {'fruits': ['pomme', 'banane']}
dd_int = defaultdict(int)
for char in "abracadabra":
dd_int[char] += 1
print(f"Comptages : {dict(dd_int)}")
# â Comptages : {'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}
dd_set = defaultdict(set)
dd_set["villes"].add("Paris")
dd_set["villes"].add("Lyon")
print(f"Ensemble : {dict(dd_set)}")
# â Ensemble : {'villes': {'Paris', 'Lyon'}}
- Ălimine le code rĂ©pĂ©titif comme
if key not in d: d[key] = []. - Rend le code plus propre et plus sûr.
11. dataclass â classes de donnĂ©es
Décorateur qui génÚre automatiquement __init__, __repr__, __eq__, etc.
from dataclasses import dataclass
@dataclass
class Personne:
nom: str
age: int
ville: str = "Non spécifiée"
alice = Personne("Alice", 25)
print(f"Objet : {alice}")
# â Objet : Personne(nom='Alice', age=25, ville='Non spĂ©cifiĂ©e')
print(f"Nom : {alice.nom}")
# â Nom : Alice
alice.age = 26
print(f"AprĂšs mise Ă jour : {alice}")
# â AprĂšs mise Ă jour : Personne(nom='Alice', age=26, ville='Non spĂ©cifiĂ©e')
bob = Personne("Bob", 30)
print(f"Alice == Bob : {alice == bob}")
# â Alice == Bob : False
@dataclass(frozen=True)
class PersonneImmutable:
nom: str
age: int
ivan = PersonneImmutable("Ivan", 40)
# ivan.age = 41 â FrozenInstanceError
- Remplace lâĂ©criture manuelle de
__init__,__repr__,__eq__. - Idéal pour les DTO, configs, modÚles.
12. UserList â listes personnalisĂ©es
Hérite de collections.UserList. Utilisé pour créer des listes avec comportement personnalisé.
from collections import UserList
class ListeAvecLogs(UserList):
def append(self, item):
print(f"[LOG] Ajout : {item}")
super().append(item)
def remove(self, item):
print(f"[LOG] Suppression : {item}")
super().remove(item)
log_list = ListeAvecLogs([1, 2, 3])
print(f"Initial : {log_list}")
# â Initial : [1, 2, 3]
log_list.append(4)
# â [LOG] Ajout : 4
print(f"AprĂšs append : {log_list}")
# â AprĂšs append : [1, 2, 3, 4]
log_list.remove(2)
# â [LOG] Suppression : 2
print(f"AprĂšs remove : {log_list}")
# â AprĂšs remove : [1, 3, 4]
- Utile pour ajouter des logs, validations, ou modifier le comportement standard des listes.
13. UserDict â dictionnaires personnalisĂ©s
Hérite de collections.UserDict. Utilisé pour créer des dicts avec comportement personnalisé.
from collections import UserDict
class DictClefsMinuscules(UserDict):
def __setitem__(self, key, value):
key = key.lower() if isinstance(key, str) else key
super().__setitem__(key, value)
def __getitem__(self, key):
key = key.lower() if isinstance(key, str) else key
return super().__getitem__(key)
ld = DictClefsMinuscules()
ld["Nom"] = "Alice"
print(f"Valeur pour 'Nom' : {ld['Nom']}")
# â Valeur pour 'Nom' : Alice
print(f"Valeur pour 'nom' : {ld['nom']}")
# â Valeur pour 'nom' : Alice
print(f"Clés : {list(ld.keys())}")
# â ClĂ©s : ['nom']
- Utilisé pour normaliser les clés, valider, logger, mettre en cache, etc.
đ Comparaison mĂ©moire et performance
Le choix de la collection impacte performance et consommation mémoire. Voici des benchmarks pratiques.
1. Mémoire : list vs tuple vs array.array
import sys
from array import array
n = 1_000_000
data = list(range(n))
data_t = tuple(range(n))
data_a = array('i', range(n))
print(f"list : {sys.getsizeof(data) / 1024 / 1024:.2f} Mo")
# â list : 8.00 Mo
print(f"tuple : {sys.getsizeof(data_t) / 1024 / 1024:.2f} Mo")
# â tuple : 8.00 Mo
print(f"array : {sys.getsizeof(data_a) / 1024 / 1024:.2f} Mo")
# â array : 3.81 Mo
array.arrayutilise ~2x moins de mémoire pour les nombres.listettupleconsomment une mémoire similaire, maistupleest légÚrement plus rapide en itération.
2. Vitesse dâaccĂšs : list vs tuple vs array.array
import time
def time_access(collection, name):
start = time.perf_counter()
total = 0
for i in range(len(collection)):
total += collection[i]
end = time.perf_counter()
print(f"{name} : {end - start:.4f} secondes")
n = 10_000_000
lst = list(range(n))
tpl = tuple(range(n))
arr = array('i', range(n))
time_access(lst, "list") # â list : 1.2000 secondes
time_access(tpl, "tuple") # â tuple : 1.0000 secondes
time_access(arr, "array") # â array : 0.8000 secondes
array.arrayest le plus rapide pour les donnĂ©es numĂ©riques.tupleest 10â20% plus rapide quelist.- La diffĂ©rence est notable Ă grande Ă©chelle.
3. Mémoire : dict vs SimpleNamespace vs dataclass
d = {"nom": "A", "age": 25, "ville": "X", "hobby": "Y", "job": "Z"}
ns = SimpleNamespace(nom="A", age=25, ville="X", hobby="Y", job="Z")
dc = PersonneDC("A", 25, "X", "Y", "Z")
print(f"dict : {sys.getsizeof(d)} octets") # â 232
print(f"SimpleNamespace : {sys.getsizeof(ns)} octets") # â 64
print(f"dataclass : {sys.getsizeof(dc)} octets") # â 64
print(f"ns.__dict__ : {sys.getsizeof(ns.__dict__)} octets") # â 232
SimpleNamespaceetdataclassconsomment autant de mémoire quedictà cause de__dict__.- Utilisez
__slots__pour économiser de la mémoire.
4. Optimisation mémoire : dataclass avec __slots__
@dataclass
class PersonneSlots:
__slots__ = ("nom", "age", "ville", "hobby", "job")
nom: str
age: int
ville: str
hobby: str
job: str
dc_slots = PersonneSlots("A", 25, "X", "Y", "Z")
print(f"dataclass + slots : {sys.getsizeof(dc_slots)} octets")
# â 80 octets
# dc_slots.new = "valeur" â AttributeError
__slots__Ă©conomise de la mĂ©moire et accĂ©lĂšre lâaccĂšs aux attributs.- Contrepartie : pas dâajout dâattributs dynamiques.
5. Vitesse de recherche : list vs set
n = 1_000_000
lst = list(range(n))
st = set(range(n))
def time_in(collection, target, name):
start = time.perf_counter()
for _ in range(1000):
_ = target in collection
end = time.perf_counter()
print(f"{name} (recherche {target}) : {end - start:.4f} secondes")
time_in(lst, 999_999, "list") # â 10.0000 secondes
time_in(st, 999_999, "set") # â 0.0005 secondes
setest des milliers de fois plus rapide quelistpour les tests dâappartenance.- Toujours utiliser
setpour les vérifications fréquentes dex in collection.
6. Mémoire : set vs frozenset
s = set(range(1000))
fs = frozenset(range(1000))
print(f"set : {sys.getsizeof(s)} octets") # â 32792
print(f"frozenset : {sys.getsizeof(fs)} octets") # â 32792
frozensetetsetconsomment une mémoire identique.- La différence est uniquement la mutabilité.
7. Vitesse dâajout : list.append vs deque.append vs deque.appendleft
from collections import deque
import time
def time_append(collection, n, method='append'):
start = time.perf_counter()
for i in range(n):
if method == 'appendleft' and hasattr(collection, 'appendleft'):
collection.appendleft(i)
else:
collection.append(i)
end = time.perf_counter()
return end - start
n = 100_000
lst = []
dq = deque()
time_list_append = time_append(lst, n) # â 0.0100 secondes
time_deque_append = time_append(dq, n) # â 0.0100 secondes
time_deque_appendleft = time_append(deque(), n, 'appendleft') # â 0.0100 secondes
# list.insert(0):
lst = []
start = time.perf_counter()
for i in range(n):
lst.insert(0, i)
end = time.perf_counter()
print(f"list.insert(0) : {end - start:.4f} secondes") # â 5.0000 secondes
deque.appendleftest en O(1), contrairement Ălist.insert(0)qui est en O(n).- Utilisez
dequepour les opérations fréquentes aux deux extrémités.
đ§ Recommandations de performance
| Situation | Utiliser | Raison |
|---|---|---|
| Stocker des nombres, mémoire critique | array.array | 2x moins de mémoire, accÚs plus rapide |
| Données immuables | tuple | Plus rapide que list, plus sûr |
Vérifications fréquentes x in collection | set / frozenset | O(1) contre O(n) pour list |
| Opérations aux deux extrémités | deque | appendleft/popleft en O(1) |
| Données structurées, mémoire critique | dataclass + __slots__ | Pas de __dict__, moins de mémoire |
| Compter les fréquences | Counter | Optimisé pour cette tùche |
| Comportement personnalisé | UserList / UserDict | Extension sûre des collections intégrées |
đ Comparaison des collections
| Type | OrdonnĂ© | Mutable | ĂlĂ©ments uniques | AccĂšs index | Doublons |
|---|---|---|---|---|---|
list | â Oui | â Oui | â Non | â Oui | â Oui |
tuple | â Oui | â Non | â Non | â Oui | â Oui |
dict | â Oui* | â Oui | ClĂ©s uniquement | â Non | Valeurs : â |
set | â Non | â Oui | â Oui | â Non | â Non |
frozenset | â Non | â Non | â Oui | â Non | â Non |
SimpleNamespace | â Oui (attrs) | â Oui | â Non (attrs peuvent se rĂ©pĂ©ter sĂ©mantiquement) | â Non | â Oui |
namedtuple | â Oui | â Non | â Non | â Oui | â Oui |
deque | â Oui | â Oui | â Non | â Oui | â Oui |
Counter | â Non | â Oui | â Non | â Non (mais a des clĂ©s) | â Oui |
defaultdict | â Oui* | â Oui | ClĂ©s uniquement | â Non | Valeurs : â |
dataclass | â Oui (champs) | â Oui (si non gelĂ©) | â Non | â Non | â Oui |
UserList | â Oui | â Oui | â Non | â Oui | â Oui |
UserDict | â Oui* | â Oui | ClĂ©s uniquement | â Non | Valeurs : â |
str | â Oui | â Non | â Non | â Oui | â Oui |
bytes | â Oui | â Non | â Non | â Oui | â Oui |
bytearray | â Oui | â Oui | â Non | â Oui | â Oui |
range | â Oui | â Non | â Non | â Oui | â Non |
array.array | â Oui | â Oui | â Non | â Oui | â Oui |
ChainMap | â Oui* | â Oui | ClĂ©s uniquement | â Non | Valeurs : â |
Enum | â Oui | â Non | â Oui (membres) | â Non | â Non |
- â depuis Python 3.7,
dict,defaultdict,UserDict,ChainMapconservent lâordre dâinsertion.
đĄ Quand utiliser quoi ?
| TĂąche | Collection |
|---|---|
| Séquence mutable | list / deque / UserList / bytearray |
| Données immuables | tuple / namedtuple / frozenset / str / bytes |
| Recherche rapide, suppression doublons | set / frozenset |
| Données structurées | dict / dataclass / SimpleNamespace / UserDict / TypedDict |
| Utilisable comme clé de dict | frozenset |
Objets temporaires avec accĂšs par . | SimpleNamespace / dataclass |
| Compter les fréquences | Counter |
| Valeurs par défaut pour clés | defaultdict |
| Opérations efficaces aux extrémités | deque |
| Comportement de liste personnalisé | UserList |
| Comportement de dict personnalisé | UserDict |
| Données binaires | bytes / bytearray / array.array |
| Configs avec hiérarchie | ChainMap |
| Constantes nommées | Enum |
| Séquences paresseuses | range / générateurs |