Activité - Problèmes de copie☘
On rappelle qu'en Python les tableaux (type list
) sont muables : on peut
changer un élément du tableau sans changer d'objet. Par conséquent,
l'affectation « =
» ne construit pas un nouvel objet mais
lui attribue une deuxième étiquette (qui affecte le même objet).
Pour vous en convaincre, étudiez de nouveau cette page du chapitre sur la Portée des variables.
Act B05.11 - Sous-tableaux distincts ?☘
On considère les instructions suivantes, saisies en console :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Anticipez les résultats des instructions des lignes 5, 11 et 17 avant de les tester dans la console.
Réponses et compléments
-
Après les deux premières instructions :
1 2 3
>>> matrice = [] >>> tab = [0]*5
on est dans la situation : Ainsi, l'instruction de la ligne 5 donne :
5 6
>>> tab [0, 0, 0, 0, 0]
-
L'instruction suivante :
8 9
>>> for i in range(3): matrice.append(tab)
Ajoute trois éléments à
matrice
qui pointent tous vers le tableautab
: L'instruction de la ligne 11 donne l'illusion que tout va bien :>>> matrice linenums="11" [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
-
Les instructions des lignes 14 et 16
montrent que l'on modifie simultanément le deuxième élément des trois lignes, ce qui n'est certainement pas l'effet désiré :14 15 16 17
>>> matrice[0][1] = 7 >>> matrice [[0, 7, 0, 0, 0], [0, 7, 0, 0, 0], [0, 7, 0, 0, 0]]
Act B05.12 - Nouveau tableau ou nouvelle étiquette ?☘
On considère les instructions suivantes, saisies en console :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
-
Rappelez la signification du test «
==
» et du test «is
».Réponse du 1.
Un test qui utilise «
==
» renvoieTrue
lorsque les deux objets comparés ont les mêmes contenus.Un test qui utilise «
is
» renvoieTrue
lorsque les deux objets comparés sont les mêmes objets en mémoire. -
Anticipez les résultats des instructions des lignes 7, 10, 13 et 16.
Réponse du 2.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
>>> A = [[1,2],[3,4]] >>> B = [[1,2],[3,4]] >>> C = A >>> A == B True >>> A is B False >>> C == A True >>> A is C True
schéma mémoire☘
Act B05.13 - Nouvelle étiquette et modification d'éléments☘
On considère les instructions suivantes, saisies en console :
1 2 3 4 5 6 7 8 9 10 |
|
Anticipez les valeurs renvoyées par les instructions des lignes 7 et 10 avant de tester ces instructions dans la console et de consulter le complément d'explication ci-dessous.
Une réponse
-
Après les deux premières instructions :
1 2 3
>>> A = [[1,2],[3,4]] >>> B = A
on est dans la situation : Toute modification de
B
entraîne donc une modification deA
. -
L'instruction suivante :
5
>>> B[1] = [42, 666]
redéfinit
B[1]
, donc redéfinitA[1]
: -
On peut le constater en testant ces instructions dans la console :
1 2 3 4 5 6 7 8 9 10 11
>>> A = [[1,2],[3,4]] >>> B = A >>> B[1] = [42, 666] >>> A [[1, 2], [42, 666]] >>> B [[1, 2], [42, 666]]
Act B05.14 - Nouveau tableau mais mêmes sous-tableaux☘
On considère les instructions suivantes, saisies en console :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
Anticipez les résultats des instructions des lignes 9, 12, 15, 18, 21, 24, 27 et 30 avant de tester ces instructions dans la console.
Réponses et compléments
-
Après les deux premières instructions :
1 2 3
>>> A = [[1,2],[3,4]] >>> B = [[], []]
on est dans la situation :
-
Après les deux instructions suivantes :
5 6 7
>>> B[0] = A[0] >>> A[1] = B[1]
on est dans la situation :
-
Ces shémas permettent de comprendre les résultats des instructions des lignes 9, 12, 15, 18, 21, 24, 27 et 30 :
On peut noter que les objets1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
>>> A = [[1,2],[3,4]] >>> B = [[], []] >>> B[0] = A[0] >>> A[1] = B[1] >>> A [[1, 2], []] >>> B [[1, 2], []] >>> B == A True >>> B[0] == A[0] True >>> B[1] == A[1] True >>> B is A False >>> B[0] is A[0] True >>> B[1] is A[1] True
A
etB
sont distincts, mais que leurs tableaux internes peuvent tout de même être le même objet.
Act B05.15 - Un même sous-tableau, pas l'autre☘
On considère les instructions suivantes, saisies en console :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
-
Anticipez les résultats des instructions des lignes 14 et 17 avant de tester ces instructions dans la console.
Réponses du 1.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
>>> A = [[1,2],[3,4]] >>> B = [[], []] >>> B[0] = A[0] >>> B[1] = A[1] >>> B[0] = [666, 42] >>> B[1][0] = 69 >>> A [[1, 2], [69, 4]] >>> B [[666, 42], [69, 4]]
-
Expliquez les résultats obtenus.
Réponses du 2. et compléments
On a vu, avec le paragraphe précédent que
B
n'est pasA
(puisqueB
est obtenu à l'aide d'une affectation d'un nouvel objet de typelist
). Ce qu'il faut ensuite comprendre est pourquoi :- la modification de
B[0]
n'affecte pasA
; - tandis que la modification de
B[1][0]
affecteA
.
Suivons les instrutions effectuées les unes après les autres.
-
Après les deux premières instructions :
on est dans la situation :1 2 3
>>> A = [[1,2],[3,4]] >>> B = [[], []]
-
Après les deux instructions suivantes :
la situation devient :5 6 7
>>> B[0] = A[0] >>> A[1] = B[1]
c'est à dire:
-
On effectue ensuite l'instruction :
9
>>> B[0] = [666, 42]
B[0]
est modifié par affectation d'un nouveau tableau, c'est-à-dire par :
- création d'un nouvel objet de typelist
:[666, 42]
;
- affectation de ce nouveau tableau àB[0]
.
PuisqueB is not A
, le tableau étiqueté parA
n'est pas affecté.
La situation est alors la suivante :
-
Ensuite,
B[1][0]
est modifié par affectation d'un nouvel objet.
MaisB[1] is A[1]
, c'est-à-dire les étiquettesB[1]
etA[1]
correspondent au même objet, donc cette affectation concerne égalementA[1]
. Ainsi, après la ligne :
la situation est la suivante :11
>>> B[1][0] = 69
- la modification de
Act B05.16 - Nouveau tableau ou nouvelle étiquette ? (bis)☘
On considère les instructions suivantes, saisies en console :
1 2 3 4 5 6 7 8 9 10 11 12 |
|
-
Anticipez les résultats des instructions des lignes 10 et 13 avant de tester ces instructions dans la console.
Réponses du 1.
1 2 3 4 5 6 7 8 9 10 11 12 13
>>> A = [[1,2],[3,4]] >>> B = A >>> B[0] = [666, 42] >>> B[1][0] = 69 >>> A [[666, 42], [69, 4]] >>> B [[666, 42], [69, 4]]
-
Expliquez les résultats obtenus.
Réponses du 2. et compléments
La différence avec le paragraphe précédent tient dans l'affectation initiale de
B
:B = A
.
A cause de cette affectation,B
est une étiquette sur l'objetA
donc toute modification des contenus deB
est une modification deA
(et vice-versa).-
Après les deux premières instructions :
on est dans la situation :1 2 3
>>> A = [[1,2],[3,4]] >>> B = A
-
Après l'instruction suivante :
la situation devient :5
>>> B[0] = [666, 42]
-
Après l'instruction suivante :
la situation devient :7
>>> B[1][0] = 69
-