Aller au contenu

Copie d'une liste de listes en python

Exercice 1

Après le code suivant:

A = [ [1,2], [3,4] ]
B = [ [1,2], [3,4] ]
C = A
  • quelles valeurs auront les tests ci-dessous:
A == B
A is B
C == A
A is C
  • Rappeler la signification de ces tests.
  • Dessiner un "schéma mémoire".
valeurs des tests
>>> 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
interprétation des tests

"A == B vaut True" traduit le fait que A et B ont les mêmes contenus.
"A is B vaut False" traduit le fait que A et B ne sont pas les mêmes objets en mémoire.
"A is C vaut True" traduit le fait que A et C sont les mêmes objets en mémoire.

schéma mémoire

Exercice 2

Après le code python suivant, quelles sont les valeurs de A et B?

A = [[1, 2], [3, 4]]
B = A
B[1] = [42, 666]
Réponse

Après les deux premières lignes

A = [[1, 2], [3, 4]]
B = A

on est dans la situation:

Toute modification de B entraîne donc une modification de A.

La ligne suivante:

B[1] = [42, 666]

redéfinit B[1], donc redéfinit A[1].

>>> A = [[1, 2], [3, 4]]
>>> B = A
>>> B[1] = [42, 666]
>>> A
[[1, 2], [42, 666]]
>>> B
[[1, 2], [42, 666]]

Exercice 3

Avec le code suivant:

>>> A = [[1,2], [3,4]]
>>> B = [[], []]
>>> B[0] = A[0]
>>> A[1] = B[1]
  • Quelles seront les réponses python (répondre d'abord sans tester sur machine!):
>>> A
>>> B
>>> B == A
>>> B[0] == A[0]
>>> B[1] == A[1]
>>> B is A
>>> B[0] is A[0]
>>> B[1] is A[1]
Réponses python

Après les lignes:

>>> A = [[1,2], [3,4]]
>>> B = [[], []]
on a la situation:

Après les lignes

>>> B[0] = A[0]
>>> A[1] = B[1]

on a la situation:

Les réponses python:

>>> 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

On notera notamment que les objets B et A sont distincts, mais que leurs listes internes peuvent tout de même être le même objet.

Exercice 4

Avec le code suivant:

>>> A = [[1,2],[3,4]]
>>> B = [[], []]
>>> B[0] = A[0]
>>> B[1] = A[1]
>>> B[0] = [666, 42]
>>> B[1][0] = 69

Qu'obtiendra-t-on avec (répondre d'abord sans machine!):

>>> A
>>> B

Expliquer.

Réponse

La réponse python:

>>> A
[[1, 2], [69, 4]]
>>> B
[[666, 42], [69, 4]]
Explication

On a vu, avec l'exercice précédent que B n'est pas A (puisque B est obtenu à l'aide d'une affectation d'un nouvel objet liste).

Ce qu'il faut ensuite comprendre est pourquoi:

  • la modification de B[0] n'affecte pas A,
  • tandis que la modification de B[1][0] affecte A.

Après les lignes:

>>> A = [[1,2], [3,4]]
>>> B = [[], []]
on a la situation:

Après les lignes:

>>> B[0] = A[0]
>>> B[1] = A[1]

la situation devient:

soit "en purgeant" un peu:

On effectue ensuite la ligne:

>>> B[0] = [666, 42]

Nous modifions B[0] par affectation d'une nouvelle liste B[0] = [666, 42]. Rappelons que l'ordre est le suivant:

  • création d'un nouvel objet liste ([666,42])
  • affectation de ce nouvel objet liste à B[0]

Par ailleurs : B is not A, A n'est pas affecté.

La situation est alors la suivante:

De même nous modifions B[1][0] par affectation d'un nouvel objet. Mais B[1] is A[1], donc cette affectation concerne A[1] également.

Après la ligne:

>>> B[1][0] = 69
la situation est la suivante:

Exercice 5

Répondre aux mêmes questions que dans l'exercice 4 en cherchant à bien comprendre les différences.

Code initial:

>>> A = [[1,2],[3,4]]
>>> B = A
>>> B[0] = [666, 42]
>>> B[1][0] = 69

Quelles réponses pour:

>>> A
>>> B
Réponse

La réponse python:

>>> A
[[666, 42], [69, 4]]
>>> B
[[666, 42], [69, 4]]
Explication

La différence tient dans l'affectation initiale de B: B = A. Donc B est une étiquette sur l'objet A. Toute modification des contenus de B est une modification de A.

Après les lignes:

>>> A = [[1,2],[3,4]]
>>> B = A

la situation est:

Après la ligne:

>>> B[0] = [666, 42]

la situation est:

Après la ligne:

>>> B[1][0] = 69

la situation est: