Quel sera l'affichage en exécutant le code ci-dessous ?
Qu'est ce qui explique le résultat affiché pour L ?
Le comportement observé est-il différent du comportement observé dans le code qui suit ?
- une aide technique
- explication
Utilisez l'opérateur is
qui permet de savoir si deux étiquettes désignent le même objet.
Par exemple :
L = [2,3,4]
M = L
print(M is L)
Dans ce cas, l'affichage est True
: M et L sont deux noms différents pour le même objet.
Résultats observés
Le résultat pour le premier code est le suivant :
[50, 2, 3]
[50, 2, 3]
Ce qu'il faut remarquer avant tout est que la liste L a également été modifiée par la modification de M[0].
Pourtant dans un code tel que :
L = 2
M = L
M = 50
print(M)
print(L)
L a bien encore la valeur 2 à la fin de l'exécution.
Le comportement n'est pas différent
Pour autant, le comportement n'est pas différent. Nous ne comparons pas ici deux situations analogues.
Le code :
L = 2
M = L
print(M is L)
M = 50
print(M is L)
et le code :
L = [1,2,3]
M = L
print(M is L)
M = [1,2,3]
print(M is L)
renvoient tous deux en premier lieu True
et en second False
.
Ce qui signifie que dans les deux cas, l'affectation M = L
a simplement pour effet
de donner une nouvelle étiquette au même objet. Tandis que le code M = 2
ou le code
M = [1,2,3]
a pour effet de créer un nouvel objet (nouvel objet qui a le même contenu que le premier
objet créé).
Des schémas
Quelques schémas peuvent aider à comprendre la situation.
Après le code :
L = 2
M = L
l'état est :
Et après le code :
L = 2
M = L # l'effet de cette ligne est éliminé du fait de l'instruction suivante !
M = 2
l'état est :
Après le code :
L = [1,2,3]
M = L
l'état est le suivant :
et après le code :
L = [1,2,3]
M = L # l'effet de cette ligne est éliminé du fait de l'instruction suivante !
M = [1,2,3]
l'état est le suivant :
Retour au premier script
Dans le cas du premier script, on commence par :
L = [1,2,3]
M = L
ce qu'on l'on peut schématiser par :
M désigne le même objet que L. M et L doivent être considérés comme deux étiquettes d'un même objet et non comme deux objets distincts. C'est l'adresse de la liste qui est copiée et non sa valeur lors de l'exécution du code
M = L
.
De ce fait, toute modification de M est aussi une modification de L (et vice-versa).
Une affectation telle que M[0] = 50
ne change pas l'adresse de la liste M mais change uniquement
le contenu de la cellule d'indice 0.
Après l'instruction M[0] = 50
, l'état de la mémoire est donc :
On peut se représenter une liste en mémoire comme une série de cases mémoires contiguẽs et les étiquettes L et M comme des pointeurs vers la première case mémoire :
On comprend dès lors que la modification de M[0]
ou L[0]
concerne le contenu de
la même case mémoire et
que M et L pointent toujours sur la même zone mémoire.