Prépa Python

Opérationnel — chapitre 24 sur 54

Références, aliasing et mutabilité

Comprendre les références Python pour éviter les pièges classiques

70 minAbonnés

Pourquoi ce code produit-il un résultat surprenant ?

python
a = [1, 2, 3]
b = a
b.append(4)
print(a)

La liste a contient maintenant 4 alors qu'on n'a modifié que b. Ce chapitre explique pourquoi, et comment éviter ce piège.

Variables et objets : le modèle Python

En Python, une variable n'est pas une case mémoire qui contient une valeur. C'est une étiquette qui pointe vers un objet en mémoire.

python
x = 42

Ce qui se passe :

  1. Python crée un objet entier 42 en mémoire.
  2. L'étiquette x est attachée à cet objet.
text
x ────► [ 42 ]

On peut visualiser cette référence avec la fonction id() qui renvoie l'identifiant unique d'un objet en mémoire :

python
x = 42
print(f"x pointe vers l'objet {id(x)}")

L'alias : deux étiquettes, un seul objet

Quand on écrit b = a, on ne copie pas les données. On crée une nouvelle étiquette qui pointe vers le même objet.

python
a = [1, 2, 3]
b = a

print(f"id(a) = {id(a)}")
print(f"id(b) = {id(b)}")
print(f"a et b pointent vers le même objet : {a is b}")
text
a ────┐
      ├───► [ 1, 2, 3 ]
b ────┘

On dit que a et b sont des alias — deux noms pour le même objet. Toute modification via b est aussi visible par a :

python
a = [1, 2, 3]
b = a

b.append(4)         # on modifie L'OBJET via b
print("a :", a)     # a voit la modification : même objet !
print("b :", b)

L'opérateur is — identité d'objet

L'opérateur is teste si deux variables pointent vers le même objet (identité), alors que == teste si leurs valeurs sont égales (égalité).

python
a = [1, 2, 3]
b = a              # alias
c = [1, 2, 3]      # nouvel objet, même contenu

print("a == b :", a == b)   # True : même contenu
print("a is b :", a is b)   # True : même objet

print("a == c :", a == c)   # True : même contenu
print("a is c :", a is c)   # False : objets différents !
text
a ────┐
      ├───► [ 1, 2, 3 ]    ← même objet
b ────┘

c ────────► [ 1, 2, 3 ]    ← autre objet, même contenu

Créer une vraie copie

Pour obtenir une copie indépendante d'une liste, on a plusieurs options :

Méthode 1 : slicing [:]

python
a = [1, 2, 3]
b = a[:]           # copie par slicing

b.append(4)
print("a :", a)    # inchangé
print("b :", b)
print(a is b)      # False : objets différents

Méthode 2 : constructeur list()

python
a = [1, 2, 3]
b = list(a)        # même effet

b.append(4)
print("a :", a)
print("b :", b)

Méthode 3 : méthode .copy()

python
a = [1, 2, 3]
b = a.copy()

b.append(4)
print("a :", a)
print("b :", b)

Tableau des techniques de copie

Méthode Copie de Notes
b = a[:] liste, tuple, str Slicing complet
b = list(a) liste Explicit
b = a.copy() liste, dict, set Méthode dédiée
b = dict(a) dict —
b = set(a) set —
b = a ❌ alias, pas une copie ! Piège

Suite réservée aux abonnés

Débloquez l'intégralité du parcours

Les 54 chapitres, les exercices corrigés automatiquement, les examens blancs et le suivi de votre progression.

Voir les offresChapitres en accès libre

Déjà un accès ? Connectez-vous.