Leçon 4/9 8 min

Listes et dictionnaires

Organisez vos données : listes, slicing, list comprehensions, dictionnaires et tuples.

Les listes

Une liste est une collection ordonnée de valeurs. On la crée avec des crochets [] :

fruits = ["pomme", "banane", "cerise"]

print(fruits[0])    # pomme (le premier)
print(fruits[-1])   # cerise (le dernier)
print(len(fruits))  # 3 (la taille)

fruits.append("kiwi")  # ajoute à la fin
fruits.pop()            # retire le dernier
fruits.remove("banane") # retire par valeur

Résultat après les opérations :

print(fruits)  # ['pomme', 'cerise']

Les indices commencent à 0, pas à 1. fruits[1] est le deuxième élément.

Le slicing : découper une liste

Le slicing extrait une portion de liste avec la syntaxe [début:fin] :

Prédisez avant de lire

Avec lettres = ['a', 'b', 'c', 'd', 'e'], que renvoient lettres[1:4] et lettres[-1] ? Avant de dérouler : pourquoi lettres[1:4] ne contient-il PAS l'élément d'indice 4 ?

Voir la réponse

lettres[1:4] renvoie ['b', 'c', 'd'] : le slicing part de l'indice de début inclus (1) et s'arrête avant l'indice de fin (4 exclu), donc indices 1, 2, 3. Même logique d'exclusion que range. lettres[-1] renvoie 'e' : un indice négatif compte depuis la fin (-1 = dernier élément, -2 = avant-dernier). Pratique pour attraper le dernier sans connaître la longueur.

nombres = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print(nombres[2:5])   # [2, 3, 4]     (index 2, 3, 4)
print(nombres[:3])    # [0, 1, 2]     (du début à 3)
print(nombres[7:])    # [7, 8, 9]     (de 7 à la fin)
print(nombres[::2])   # [0, 2, 4, 6, 8]  (un sur deux)
print(nombres[::-1])  # [9, 8, 7, ..., 0] (inversé)

La règle : le début est inclus, la fin est exclue. C'est logique une fois qu'on s'y habitue.

List comprehensions : le superpouvoir de Python

Les list comprehensions créent des listes en une seule ligne :

# Doubler chaque nombre
doubles = [x * 2 for x in range(5)]
print(doubles)  # [0, 2, 4, 6, 8]

# Filtrer les nombres pairs
pairs = [x for x in range(10) if x % 2 == 0]
print(pairs)    # [0, 2, 4, 6, 8]

# Mettre en majuscules
noms = ["alice", "bob", "charlie"]
majuscules = [nom.upper() for nom in noms]
print(majuscules)  # ['ALICE', 'BOB', 'CHARLIE']

La syntaxe : [expression for élément in iterable if condition]. C'est l'une des raisons pour lesquelles les développeurs adorent Python.

Les dictionnaires

Un dictionnaire associe des clés à des valeurs. On le crée avec des accolades {} :

utilisateur = {
    "nom": "Alice",
    "age": 25,
    "ville": "Paris"
}

print(utilisateur["nom"])     # Alice
print(utilisateur.get("age")) # 25

# Ajouter / modifier
utilisateur["email"] = "alice@mail.com"
utilisateur["age"] = 26

# Parcourir
for cle, valeur in utilisateur.items():
    print(f"{cle}: {valeur}")

Résultat :

nom: Alice
age: 26
ville: Paris
email: alice@mail.com
Comparaison entre une liste, accessible par position (indice), et un dictionnaire, accessible par clé. Liste 0 1 2 3 pomme kiwi fraise cassis accès par position : ma_liste[0] Dictionnaire "nom" Alice "age" 30 "ville" Lyon accès par clé : mon_dict["nom"]
La liste se lit par position, le dictionnaire par clé.

Les ensembles (set)

Un ensemble (set) est une collection sans doublon et non ordonnée. On le crée avec des accolades {}, comme un dictionnaire, mais sans clés. Les valeurs en double disparaissent automatiquement :

mon_set = {1, 2, 2, 3}
print(mon_set)  # {1, 2, 3} : le doublon a disparu

# Dédoublonner une liste en une ligne
nombres = [4, 4, 7, 1, 7, 4]
uniques = set(nombres)
print(uniques)  # {1, 4, 7}

# Tester l'appartenance (très rapide)
print(3 in mon_set)   # True
print(9 in mon_set)   # False

# Ajouter une valeur
mon_set.add(5)
print(mon_set)  # {1, 2, 3, 5}

# Union (|) et intersection (&)
a = {1, 2, 3}
b = {2, 3, 4}
print(a | b)  # {1, 2, 3, 4} : tout ce qui est dans a OU b
print(a & b)  # {2, 3} : ce qui est dans a ET b

À quoi ça sert ? À garantir l'unicité des valeurs et à faire des tests d'appartenance très rapides (bien plus rapides que sur une liste).

Les tuples : des listes immuables

Un tuple est comme une liste, mais on ne peut pas le modifier après création :

coordonnees = (48.8566, 2.3522)  # Paris
print(coordonnees[0])  # 48.8566
# coordonnees[0] = 0   # ERREUR ! Un tuple est immuable

# Utile pour les valeurs qui ne doivent pas changer
jours = ("lundi", "mardi", "mercredi", "jeudi", "vendredi")
couleurs_rgb = (255, 128, 0)

Utilisez un tuple quand les données sont fixes (coordonnées, jours de la semaine, constantes).

Lists

A list is an ordered collection of values. Create one with square brackets []:

fruits = ["apple", "banana", "cherry"]

print(fruits[0])    # apple (the first)
print(fruits[-1])   # cherry (the last)
print(len(fruits))  # 3 (the length)

fruits.append("kiwi")    # add to the end
fruits.pop()              # remove the last
fruits.remove("banana")   # remove by value

Result after operations:

print(fruits)  # ['apple', 'cherry']

Indices start at 0, not 1. fruits[1] is the second element.

Slicing — cutting a list

Slicing extracts a portion of a list with the syntax [start:end]:

Predict before reading

With letters = ['a', 'b', 'c', 'd', 'e'], what do letters[1:4] and letters[-1] return? Before unfolding: why does letters[1:4] NOT include the element at index 4?

See the answer

letters[1:4] returns ['b', 'c', 'd']: slicing starts from the start index included (1) and stops before the end index (4 excluded), so indices 1, 2, 3. Same exclusion logic as range. letters[-1] returns 'e': a negative index counts from the end (-1 = last element, -2 = second to last). Handy to grab the last element without knowing the length.

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print(numbers[2:5])   # [2, 3, 4]     (index 2, 3, 4)
print(numbers[:3])    # [0, 1, 2]     (from start to 3)
print(numbers[7:])    # [7, 8, 9]     (from 7 to end)
print(numbers[::2])   # [0, 2, 4, 6, 8]  (every other)
print(numbers[::-1])  # [9, 8, 7, ..., 0] (reversed)

The rule: start is included, end is excluded. It makes sense once you get used to it.

List comprehensions — Python's superpower

List comprehensions create lists in a single line:

# Double each number
doubles = [x * 2 for x in range(5)]
print(doubles)  # [0, 2, 4, 6, 8]

# Filter even numbers
evens = [x for x in range(10) if x % 2 == 0]
print(evens)    # [0, 2, 4, 6, 8]

# Uppercase names
names = ["alice", "bob", "charlie"]
upper_names = [name.upper() for name in names]
print(upper_names)  # ['ALICE', 'BOB', 'CHARLIE']

The syntax: [expression for element in iterable if condition]. This is one of the reasons developers love Python.

Dictionaries

A dictionary maps keys to values. Create one with curly braces {}:

user = {
    "name": "Alice",
    "age": 25,
    "city": "Paris"
}

print(user["name"])      # Alice
print(user.get("age"))   # 25

# Add / modify
user["email"] = "alice@mail.com"
user["age"] = 26

# Iterate
for key, value in user.items():
    print(f"{key}: {value}")

Result:

name: Alice
age: 26
city: Paris
email: alice@mail.com
Comparison between a list, accessed by position (index), and a dictionary, accessed by key. List 0 1 2 3 apple kiwi grape currant access by position: my_list[0] Dictionary "name" Alice "age" 30 "city" Lyon access by key: my_dict['name']
A list is read by position, a dictionary by key.

Sets

A set is an unordered collection without duplicates. You create one with curly braces {}, like a dictionary, but without keys. Duplicate values disappear automatically:

my_set = {1, 2, 2, 3}
print(my_set)  # {1, 2, 3}: the duplicate is gone

# Deduplicate a list in one line
numbers = [4, 4, 7, 1, 7, 4]
unique = set(numbers)
print(unique)  # {1, 4, 7}

# Test membership (very fast)
print(3 in my_set)   # True
print(9 in my_set)   # False

# Add a value
my_set.add(5)
print(my_set)  # {1, 2, 3, 5}

# Union (|) and intersection (&)
a = {1, 2, 3}
b = {2, 3, 4}
print(a | b)  # {1, 2, 3, 4}: everything in a OR b
print(a & b)  # {2, 3}: what is in a AND b

What is it for? To guarantee the uniqueness of values and to perform very fast membership tests (much faster than on a list).

Tuples — immutable lists

A tuple is like a list, but you can't modify it after creation:

coordinates = (48.8566, 2.3522)  # Paris
print(coordinates[0])  # 48.8566
# coordinates[0] = 0   # ERROR! A tuple is immutable

# Useful for values that should not change
days = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday")
rgb_color = (255, 128, 0)

Use a tuple when data is fixed (coordinates, days of the week, constants).

🎯 Pratique

S'entraîner (clique pour ouvrir) :

Prompt IA
Avec l'IA

Copiez ce prompt dans Claude ou ChatGPT :

Écris un script Python qui crée un dictionnaire de contacts (nom, téléphone, email) et permet d'ajouter, rechercher et supprimer des contacts. Utilise une list comprehension pour filtrer les contacts.
💬 Ré-explique sans regarder
Ré-explique sans regarder

Sans relire la réponse de l'IA : avec tes mots, quand choisis-tu un dictionnaire plutôt qu'une liste pour stocker des données ?

Une bonne explication dit : la liste sert quand l'ordre compte et qu'on accède par position (fruits[0]) ; le dictionnaire sert quand chaque donnée a un nom et qu'on accède par clé (user["nom"]). Pour les contacts du prompt, le dictionnaire est naturel : chaque champ (nom, téléphone, email) est une clé, pas une position à retenir. Bonus : l'accès par clé reste rapide même avec beaucoup d'entrées.
⚖️ Juge le code de l'IA
Accepter ou rejeter le code de l'IA

Tu lui demandes de dédoublonner une liste. L'IA propose ce code. Ton rôle de relecteur : l'accepter tel quel ou le rejeter, et dire pourquoi.

uniques = []
for valeur in nombres:
    if valeur not in uniques:
        uniques.append(valeur)
À rejeter (ou plutôt simplifier). Le code marche, mais le not in uniques rescanne toute la liste à chaque tour : sur une grosse liste ça devient lent. Python a l'outil fait pour ça : uniques = set(nombres) dédoublonne en une ligne avec des tests d'appartenance bien plus rapides. Seule réserve : un set ne garde pas l'ordre ; si l'ordre compte, list(dict.fromkeys(nombres)) fait le travail. La boucle manuelle n'est pas un bug, mais ce n'est pas le réflexe Python.
🧠 Rappel libre
Rappel libre

Sans remonter dans la leçon : comment accède-t-on à une valeur dans une liste vs dans un dictionnaire, et que renvoie [0,1,2,3,4][1:3] ?

Dans une liste, on accède par position : fruits[0] (l'indice commence à 0). Dans un dictionnaire, par clé : user["nom"]. [0,1,2,3,4][1:3] renvoie [1, 2] : le début (index 1) est inclus, la fin (index 3) est exclue.
Que renvoie fruits[-1] si fruits = ["pomme", "banane", "cerise"] ?
Que produit [x * 2 for x in range(4)] ?
Comment accéder à la valeur "Paris" dans user = {"nom": "Alice", "ville": "Paris"} ?
Quelle est la différence entre une liste et un tuple ?
Prochaine étape

Vous savez stocker et parcourir des données. Le réflexe suivant : éviter de copier-coller le même code partout. On découvre les fonctions, avec def, les paramètres par défaut, *args et **kwargs.

Leçon 5 : Les fonctions →

Une erreur dans cette leçon, un passage flou, une question ? Écrivez-moi : chaque retour améliore ce cours.

Besoin d'un développeur pour votre projet ?

Réponse sous 24h · Sans engagement