Copier un tableau☘
Plusieurs étiquettes sur un tableau☘
Puisque les objets de type list
sont muables, le symbole d'affectation
« =
» permet-il de copier le contenu d'un tableau dans une
autre variable ?
Pour répondre à cette question, on considère les instructions suivantes :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
-
Anticipez le contenu des tableaux
a
,b
etc
dans les dernières lignes.Affichages
>>> a = [2, 3, 4, 5, 6] >>> b = a >>> c = [2, 3, 4, 5, 6] >>> b[len(b)-1] = 666 >>> a[0] = 42 >>> a [42, 3, 4, 5, 666] >>> b [42, 3, 4, 5, 666] >>> c [2, 3, 4, 5, 6]
-
Cherchez à expliquer ces résultats avant de consulter les explications ci-dessous.
Explications des lignes 1 à 5
- En ligne 1, l'objet de type
list
et de valeur[2, 3, 4, 5, 6]
est construit puis on lui attribue l'étiquettea
: - En ligne 3,
b = a
a pour effet de coller une seconde étiquette sur l'objet de typelist
précédent. - En ligne 5, un nouvel objet de type
list
et de valeur[2, 3, 4, 5, 6]
est construit puis on lui attribue l'étiquettec
: Attention, le contenu dec
est le même que celui dea
, mais le conteneur n'est pas le même (on a deux bouteilles contenant chacune un litre de lait, mais il y a bien deux bouteilles différentes).
Explications des lignes 7 et 9
- En ligne 7, on modifie le contenu de l'objet
list
étiquetéb
:
Cet objet porte aussi l'étiquette
a
donc l'effet aurait été le même avec l'instructiona[len(a)-1] = 666
.- En ligne 9, on modifie le contenu de l'objet
list
étiquetéa
:
Cet objet porte aussi l'étiquette
b
donc l'effet aurait été le même avec l'instructionb[0] = 42
.- Dans les lignes suivantes, on voit que les modifications faites sur
a
l'ont été aussi surb
. Le tableauc
quant à lui reste inchangé (il s'agit bien d'une autre bouteille).
Avec Python Tutor
Le site Python tutor permet de visualiser qu'un objet peut disposer de plusieurs noms (étiquettes) :
- En ligne 1, l'objet de type
Un objet a-t-il plusieurs étiquettes ?☘
Méthode
Pour vérifier si deux noms de variables (deux étiquettes) désignent le
même objet, on peut utiliser l'opérateur is
en Python.
Copiez/collez/exécutez les instructions suivantes afin de comprendre le rôle de cet opérateur :
>>> a = [2, 3, 4, 5, 6]
>>> b = a
>>> c = [2, 3, 4, 5, 6]
>>> a == b
True
>>> a is b
True
>>> a == c # même contenu
True
>>> a is c # bouteille différente
False
Pour aller plus loin
En Python, toutes les variables, quel que soit leur type, sont des objets. Contrairement à d'autres langages de programmation (comme le C ou le Java), le choix a été fait d'un typage dynamique pour rendre la manipulation de ces objets plus « facile ». En contrepartie, dans le cas d'un objet complexe, muable et donc potentiellement lourd en mémoire, c'est l'action la plus rapide qui est privilégiée par le langage.
Le type list
fait partie de ces objets potentiellement lourds.
Pour éviter une occupation mémoire inutile, l'affectation « =
» crée une
nouvelle étiquette (on parle « d'alias ») pour le tableau
plutôt qu'un nouveau tableau.
Copie de tableau☘
Exemple
On a saisi les instructions ci-dessous dans la console afin que le
tableau L1
contienne les entiers successifs de 0
à 10
tandis que
le tableau L2
contienne les entiers successifs de 0
à 9
suivis de
11
. Est-ce le cas ?
>>> L1 = list(range(11))
>>> L2 = L1
>>> L2[10] = 11
Réponse
Bien évidemment, ce n'est pas le cas puisque l'instruction L2 = L1
ne fait qu'ajouter une étiquette au même tableau. Par conséquent,
l'instruction L2[10] = 11
s'applique au même tableau d'étiquettes
L1
et L2
.
Ajoutons des lignes pour s'en convaincre :
>>> L1 = list(range(11))
>>> L1
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> L2 = L1
>>> L2[10] = 11
>>> L2
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
>>> L1
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
Cet exemple montre qu'il faut faire attention lorsqu'on souhaite copier un tableau dans une autre variable. Plusieurs solutions sont possibles dans le cas de tableaux simples, c'est-à-dire d'un tableau qui ne contient pas lui-même des tableaux.
Méthodes pour copier un tableau « simple »☘
-
La copie en utilisant la fonction
list()
:>>> L2 = list(L1)
-
La copie par compréhension :
>>> L2 = [element for element in L1]
-
La copie élément par élément à l'aide d'une fonction :
puis1 2 3 4 5 6 7 8 9
def copie(tab): """ tab - list Sortie: list - Renvoie un tableau de même contenu que tab """ nouv_tab = [] for element in tab: nouv_tab.append(element) return nouv_tab
>>> L2 = copie(L1)
Explications
Voyons un peu le détail avec l'appel suivant :
L = [3, 4, 2, 1] T = copier(L)
L'instruction
L = [3, 4, 2, 1]
conduit à la situation :Dans l'instruction suivante
T = copier(L)
, la priorité est l'appel à la fonctioncopier()
(partie droite de l'instruction d'affectation).
La situation devient :La ligne 6 du programme (
nouv_tab = []
) est ensuite exécutée :Puis on exécute les lignes 7 et 8 :
Enfin la fonction renvoie le tableau
nouv_tab
et on l'affecte à l'étiquetteT
: -
La copie en important la fonction
copy()
contenue dans le modulecopy
:>>> from copy import copy >>> L2 = copy(L1)