Structures de données
Organisez et manipulez vos données efficacement
Structures de données en Python : listes, tuples, dictionnaires et ensembles
Les structures de données sont des formats spécialisés pour organiser, stocker et manipuler des informations. Python dispose de plusieurs structures de données intégrées qui facilitent la gestion des collections d’éléments. Dans ce tutoriel, nous allons explorer les quatre structures de données principales de Python : listes, tuples, dictionnaires et ensembles.
Comprendre ces structures et savoir quand utiliser chacune d’elles est essentiel pour écrire du code Python efficace et élégant.
Listes
Les listes sont l’une des structures de données les plus polyvalentes et fréquemment utilisées en Python. Une liste est une collection ordonnée et modifiable d’éléments.
Création de listes
# Liste vide
ma_liste = []
# Liste avec des éléments
nombres = [1, 2, 3, 4, 5]
fruits = ["pomme", "banane", "orange"]
mixte = [1, "hello", 3.14, True] # Peut contenir différents types
# Création avec la fonction list()
caracteres = list("Python") # ['P', 'y', 't', 'h', 'o', 'n']
Accès aux éléments d’une liste
Les éléments d’une liste sont indexés à partir de 0.
fruits = ["pomme", "banane", "orange", "fraise", "kiwi"]
# Accès par index positif (depuis le début)
premier_fruit = fruits[0] # "pomme"
troisieme_fruit = fruits[2] # "orange"
# Accès par index négatif (depuis la fin)
dernier_fruit = fruits[-1] # "kiwi"
avant_dernier = fruits[-2] # "fraise"
# Découpage (slicing)
deux_premiers = fruits[0:2] # ["pomme", "banane"]
du_deuxieme_au_quatrieme = fruits[1:4] # ["banane", "orange", "fraise"]
tous_sauf_premier = fruits[1:] # ["banane", "orange", "fraise", "kiwi"]
trois_premiers = fruits[:3] # ["pomme", "banane", "orange"]
Modification des listes
fruits = ["pomme", "banane", "orange"]
# Modification d'un élément
fruits[1] = "poire" # ["pomme", "poire", "orange"]
# Ajout d'éléments
fruits.append("fraise") # Ajoute à la fin: ["pomme", "poire", "orange", "fraise"]
fruits.insert(1, "kiwi") # Insère à l'index 1: ["pomme", "kiwi", "poire", "orange", "fraise"]
fruits.extend(["cerise", "raisin"]) # Ajoute plusieurs éléments: ["pomme", "kiwi", "poire", "orange", "fraise", "cerise", "raisin"]
# Suppression d'éléments
fruits.remove("poire") # Supprime la première occurrence de "poire"
fruit_supprime = fruits.pop(2) # Supprime et retourne l'élément à l'index 2
del fruits[0] # Supprime l'élément à l'index 0
fruits.clear() # Vide la liste complètement
Opérations courantes sur les listes
nombres = [3, 1, 4, 1, 5, 9, 2, 6]
# Longueur
longueur = len(nombres) # 8
# Minimum et maximum
minimum = min(nombres) # 1
maximum = max(nombres) # 9
# Somme
total = sum(nombres) # 31
# Tri
nombres.sort() # Trie la liste en place: [1, 1, 2, 3, 4, 5, 6, 9]
nombres_decroissants = sorted(nombres, reverse=True) # Retourne une nouvelle liste triée: [9, 6, 5, 4, 3, 2, 1, 1]
# Inversion
nombres.reverse() # Inverse la liste en place
# Comptage
occurrences_de_1 = nombres.count(1) # 2
# Recherche d'index
premier_index_de_1 = nombres.index(1) # Index de la première occurrence de 1
Compréhension de liste
La compréhension de liste est une syntaxe concise pour créer des listes basées sur des séquences existantes.
# Sans compréhension de liste
carres = []
for x in range(10):
carres.append(x**2)
# Avec compréhension de liste
carres = [x**2 for x in range(10)] # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# Avec condition
nombres_pairs = [x for x in range(20) if x % 2 == 0] # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
# Compréhension de liste plus complexe
matrice = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
aplati = [nombre for ligne in matrice for nombre in ligne] # [1, 2, 3, 4, 5, 6, 7, 8, 9]
Cas d’usage courants des listes
Les listes sont idéales quand vous avez besoin de :
- Stocker une collection d’éléments dans un ordre spécifique
- Modifier fréquemment la collection (ajouter/supprimer des éléments)
- Accéder aux éléments par leur position
- Stocker des doublons
Exemples d’applications :
- Liste de tâches
- Historique d’actions
- Files d’attente de traitement
- Séries temporelles de données
Tuples
Les tuples sont similaires aux listes, mais ils sont immuables (ne peuvent pas être modifiés après leur création). Cette caractéristique les rend plus efficaces en termes de mémoire et de performances.
Création de tuples
# Tuple vide
mon_tuple = ()
# Tuple avec un seul élément (nécessite une virgule)
singleton = (42,)
# Tuple avec plusieurs éléments
coordonnees = (10, 20)
personne = ("Alice", 30, "Ingénieure")
# Création sans parenthèses (packing)
autre_tuple = 1, 2, 3
# Création avec la fonction tuple()
caracteres = tuple("Python") # ('P', 'y', 't', 'h', 'o', 'n')
Accès aux éléments d’un tuple
L’accès aux éléments d’un tuple fonctionne comme pour les listes :
coordonnees = (10, 20, 30, 40, 50)
x = coordonnees[0] # 10
y = coordonnees[1] # 20
dernier = coordonnees[-1] # 50
sous_tuple = coordonnees[1:4] # (20, 30, 40)
Déballage de tuple (unpacking)
Une caractéristique particulièrement utile des tuples est le déballage :
# Déballage basique
point = (10, 20)
x, y = point # x = 10, y = 20
# Déballage avec * pour capturer plusieurs éléments
premier, *milieu, dernier = (1, 2, 3, 4, 5)
# premier = 1, milieu = [2, 3, 4], dernier = 5
# Échange de variables
a, b = 1, 2
a, b = b, a # a = 2, b = 1
Opérations sur les tuples
coordonnees = (10, 20, 30)
plus_dimensions = coordonnees + (40, 50) # Concaténation: (10, 20, 30, 40, 50)
repete = coordonnees * 2 # Répétition: (10, 20, 30, 10, 20, 30)
Méthodes de tuple
Comme les tuples sont immuables, ils ont moins de méthodes que les listes :
nombres = (3, 1, 4, 1, 5, 9, 2)
longueur = len(nombres) # 7
occurrences_de_1 = nombres.count(1) # 2
premier_index_de_1 = nombres.index(1) # 1
Cas d’usage courants des tuples
Les tuples sont préférables lorsque :
- Vous avez une collection d’éléments qui ne changera pas
- Vous voulez empêcher la modification accidentelle des données
- Vous avez besoin d’une clé hashable pour les dictionnaires (les listes ne peuvent pas être des clés)
- Vous retournez plusieurs valeurs d’une fonction
Exemples d’applications :
- Coordonnées (x, y, z)
- Enregistrements de base de données
- Clés composées
- Valeurs RGB des couleurs
- Paramètres de configuration fixés
Dictionnaires
Les dictionnaires sont des collections non ordonnées de paires clé-valeur. Ils permettent un accès, une insertion et une suppression rapides des éléments par clé.
Création de dictionnaires
# Dictionnaire vide
mon_dict = {}
# Dictionnaire avec des paires clé-valeur
etudiant = {
"nom": "Martin",
"age": 22,
"cours": ["Mathématiques", "Informatique", "Physique"]
}
# Création avec la fonction dict()
coordonnees = dict(x=10, y=20, z=30)
# Création à partir de tuples clé-valeur
items = [("pomme", 3), ("banane", 5), ("orange", 2)]
inventaire = dict(items)
# Dictionnaire par compréhension
carre_des_nombres = {x: x**2 for x in range(6)} # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
Accès et modification des valeurs
etudiant = {
"nom": "Martin",
"age": 22,
"cours": ["Mathématiques", "Informatique", "Physique"]
}
# Accès aux valeurs
nom = etudiant["nom"] # "Martin"
# Modification des valeurs
etudiant["age"] = 23
etudiant["cours"].append("Chimie")
# Accès sécurisé avec get()
telephone = etudiant.get("telephone") # None car la clé n'existe pas
telephone = etudiant.get("telephone", "Non spécifié") # Valeur par défaut "Non spécifié"
# Ajout d'une nouvelle paire clé-valeur
etudiant["email"] = "martin@example.com"
# Suppression
cours = etudiant.pop("cours") # Supprime et retourne la valeur
del etudiant["age"] # Supprime la paire clé-valeur
etudiant.clear() # Vide le dictionnaire
Méthodes de dictionnaire
produits = {
"pomme": 0.80,
"banane": 0.50,
"orange": 0.70
}
# Récupération des clés, valeurs et items
cles = produits.keys() # dict_keys(['pomme', 'banane', 'orange'])
valeurs = produits.values() # dict_values([0.8, 0.5, 0.7])
items = produits.items() # dict_items([('pomme', 0.8), ('banane', 0.5), ('orange', 0.7)])
# Mise à jour du dictionnaire
nouveaux_produits = {"kiwi": 1.20, "banane": 0.55}
produits.update(nouveaux_produits) # Ajoute "kiwi" et modifie le prix de "banane"
# Vérification de l'existence d'une clé
if "pomme" in produits:
print("Le prix des pommes est", produits["pomme"])
Itération sur les dictionnaires
produits = {
"pomme": 0.80,
"banane": 0.50,
"orange": 0.70
}
# Itération sur les clés (comportement par défaut)
for produit in produits:
print(produit)
# Itération sur les valeurs
for prix in produits.values():
print(prix)
# Itération sur les paires clé-valeur
for produit, prix in produits.items():
print(f"{produit}: {prix}€")
Dictionnaires imbriqués
# Dictionnaire de dictionnaires
etudiants = {
"101": {
"nom": "Alice",
"age": 22,
"cours": ["Math", "Informatique"]
},
"102": {
"nom": "Bob",
"age": 21,
"cours": ["Physique", "Biologie"]
}
}
# Accès aux éléments imbriqués
nom_etudiant_102 = etudiants["102"]["nom"] # "Bob"
cours_alice = etudiants["101"]["cours"][1] # "Informatique"
Cas d’usage courants des dictionnaires
Les dictionnaires sont parfaits pour :
- Les collections où vous recherchez des éléments par une clé unique
- Le stockage de données associatives (paires clé-valeur)
- Les tables de hachage rapides pour la recherche
- La représentation d’objets avec des attributs
Exemples d’applications :
- Cache de données
- Comptage de fréquences
- Bases de données en mémoire
- Paramètres de configuration
- Stockage de propriétés d’objets JSON
Ensembles
Les ensembles (sets) sont des collections non ordonnées d’éléments uniques. Ils sont optimisés pour tester l’appartenance et éliminer les doublons.
Création d’ensembles
# Ensemble vide (ne peut pas utiliser {}, car cela crée un dictionnaire vide)
mon_ensemble = set()
# Ensemble avec des éléments
couleurs = {"rouge", "vert", "bleu"}
# Création à partir d'une liste (élimine les doublons)
nombres = set([1, 2, 2, 3, 4, 4, 5]) # {1, 2, 3, 4, 5}
# Ensemble par compréhension
nombres_pairs = {x for x in range(10) if x % 2 == 0} # {0, 2, 4, 6, 8}
Opérations sur les ensembles
fruits1 = {"pomme", "banane", "orange"}
fruits2 = {"orange", "kiwi", "ananas"}
# Ajout et suppression d'éléments
fruits1.add("fraise")
fruits1.remove("banane") # Lève une erreur si l'élément n'existe pas
fruits1.discard("cerise") # Ne lève pas d'erreur si l'élément n'existe pas
element = fruits1.pop() # Supprime et retourne un élément arbitraire
fruits1.clear() # Vide l'ensemble
# Vérification d'appartenance
"orange" in fruits2 # True
"banane" in fruits2 # False
Opérations ensemblistes
Les ensembles permettent d’effectuer des opérations mathématiques ensemblistes :
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
# Union (éléments qui sont dans A OU dans B)
union = A | B # {1, 2, 3, 4, 5, 6, 7, 8}
# ou
union = A.union(B)
# Intersection (éléments qui sont dans A ET dans B)
intersection = A & B # {4, 5}
# ou
intersection = A.intersection(B)
# Différence (éléments qui sont dans A mais PAS dans B)
difference = A - B # {1, 2, 3}
# ou
difference = A.difference(B)
# Différence symétrique (éléments qui sont dans A OU B mais PAS dans les deux)
diff_sym = A ^ B # {1, 2, 3, 6, 7, 8}
# ou
diff_sym = A.symmetric_difference(B)
# Vérifier si un ensemble est un sous-ensemble d'un autre
est_sous_ensemble = {1, 2}.issubset(A) # True
# Vérifier si un ensemble est un sur-ensemble d'un autre
est_sur_ensemble = A.issuperset({1, 2}) # True
Ensembles gelés (frozenset)
Un frozenset
est un ensemble immuable, ce qui le rend hashable. Il peut être utilisé comme clé de dictionnaire.
# Création d'un frozenset
couleurs_primaires = frozenset(["rouge", "bleu", "jaune"])
# Utilisation comme clé de dictionnaire
groupes_couleurs = {
frozenset(["rouge", "bleu", "jaune"]): "primaires",
frozenset(["violet", "orange", "vert"]): "secondaires"
}
Cas d’usage courants des ensembles
Les ensembles sont particulièrement utiles pour :
- Éliminer les doublons d’une collection
- Tester rapidement l’appartenance d’éléments
- Effectuer des opérations mathématiques sur des ensembles
- Trouver les éléments uniques ou communs entre collections
Exemples d’applications :
- Filtrage de doublons
- Analyse de données uniques
- Opérations sur des ensembles de tags
- Gestion de permissions d’utilisateurs
- Représentation de graphes (théorie des ensembles)
Choisir la bonne structure de données
Chaque structure de données a ses forces et ses faiblesses. Voici un tableau comparatif pour vous aider à choisir la plus adaptée à votre besoin :
Structure | Ordonnée | Modifiable | Éléments indexés | Élément clé-valeur | Éléments uniques | Cas d’usage typique |
---|---|---|---|---|---|---|
Liste | ✅ | ✅ | ✅ | ❌ | ❌ | Collection ordonnée modifiable |
Tuple | ✅ | ❌ | ✅ | ❌ | ❌ | Collection ordonnée immuable |
Dictionnaire | ❌¹ | ✅ | ❌ | ✅ | ✅ (clés) | Mappage clé-valeur |
Ensemble | ❌ | ✅ | ❌ | ❌ | ✅ | Élimination des doublons, opérations ensemblistes |
¹ Depuis Python 3.7, les dictionnaires conservent l’ordre d’insertion, mais ils ne sont pas considérés comme intrinsèquement ordonnés dans leur conception.
Conseils pour choisir la structure appropriée
- Utilisez une liste quand l’ordre et la modification sont importants
- Utilisez un tuple pour des données en lecture seule ou des clés composites
- Utilisez un dictionnaire pour des recherches rapides par clé
- Utilisez un ensemble quand l’unicité et les opérations ensemblistes sont nécessaires
Exemple pratique : Analyse de données
Voici un exemple qui utilise toutes les structures de données pour analyser des ventes :
# Données de ventes (produit, quantité, prix, catégorie)
ventes = [
("pomme", 5, 0.80, "fruits"),
("banane", 3, 0.50, "fruits"),
("pain", 2, 1.20, "boulangerie"),
("lait", 1, 0.90, "laitier"),
("fromage", 2, 2.50, "laitier"),
("pomme", 2, 0.80, "fruits"),
("yaourt", 4, 0.60, "laitier")
]
# Utilisation de dictionnaires pour regrouper par catégorie
ventes_par_categorie = {}
for produit, quantite, prix, categorie in ventes:
if categorie not in ventes_par_categorie:
ventes_par_categorie[categorie] = []
ventes_par_categorie[categorie].append((produit, quantite, prix))
# Utilisation d'ensembles pour obtenir des produits uniques
produits_uniques = {produit for produit, _, _, _ in ventes}
print(f"Produits uniques: {produits_uniques}") # {'pain', 'pomme', 'fromage', 'lait', 'yaourt', 'banane'}
# Utilisation de tuples pour stocker les totaux par catégorie (immuable)
totaux_par_categorie = tuple(
(categorie, sum(quantite * prix for _, quantite, prix in produits))
for categorie, produits in ventes_par_categorie.items()
)
print("Totaux par catégorie:", totaux_par_categorie)
# Utilisation de listes et de compréhensions pour analyser les ventes
total_par_produit = {}
for produit, quantite, prix, _ in ventes:
if produit in total_par_produit:
total_par_produit[produit] = (total_par_produit[produit][0] + quantite, prix)
else:
total_par_produit[produit] = (quantite, prix)
# Liste triée des produits par chiffre d'affaires
ca_par_produit = [(produit, quantite * prix) for produit, (quantite, prix) in total_par_produit.items()]
ca_par_produit.sort(key=lambda x: x[1], reverse=True)
print("Produits par chiffre d'affaires:")
for produit, ca in ca_par_produit:
print(f"- {produit}: {ca:.2f}€")
Performances des structures de données
Pour des applications qui manipulent de grandes quantités de données, les performances deviennent importantes. Voici un aperçu des complexités temporelles pour les opérations courantes :
Opération | Liste | Tuple | Dictionnaire | Ensemble |
---|---|---|---|---|
Accès par index | O(1) | O(1) | N/A | N/A |
Accès par clé | N/A | N/A | O(1)¹ | N/A |
Recherche d’élément | O(n) | O(n) | O(1)¹ | O(1)¹ |
Ajout d’élément | O(1)² | N/A | O(1)¹ | O(1)¹ |
Suppression d’élément | O(n) | N/A | O(1)¹ | O(1)¹ |
¹ En moyenne. Dans le pire des cas (rares), ces opérations peuvent être O(n).
² L’ajout à la fin est O(1) amorti. L’insertion au milieu est O(n).
Conclusion
Les structures de données sont les blocs de construction fondamentaux de tout programme Python. Comprendre leurs caractéristiques, avantages et inconvénients vous aidera à écrire un code plus efficace et plus élégant.
Pour récapituler :
- Les listes sont polyvalentes et modifiables, parfaites pour les collections ordonnées
- Les tuples sont immuables et efficaces, idéaux pour les données en lecture seule
- Les dictionnaires offrent des recherches rapides par clé, parfaits pour les associations
- Les ensembles éliminent les doublons et permettent des opérations ensemblistes efficaces
Choisir la bonne structure pour chaque situation est une compétence qui s’améliore avec la pratique. N’hésitez pas à expérimenter avec différentes approches pour résoudre vos problèmes de données.
Dans le prochain tutoriel, nous explorerons les fonctions en Python et comment les utiliser pour organiser et réutiliser votre code efficacement.
Besoin de réviser les bases de Python ? Consultez notre tutoriel sur les bases de la syntaxe Python.
Commentaires
Les commentaires sont alimentés par GitHub Discussions
Connectez-vous avec GitHub pour participer à la discussion