Affichage des articles dont le libellé est poo. Afficher tous les articles
Affichage des articles dont le libellé est poo. Afficher tous les articles

lundi 23 mars 2009

Python et la copie de listes : attention aux pièges

La copie de listes en Python est une opération qui recèle quelques subtilités liées à la manipulation des objets (Dans Python, tout est objet !). J'ai déjà écrit sur le sujet ici.
Il faut davantage se méfier de la copie de listes de listes, c'est à dire de listes composées de listes !!!

Le problème
Si l'on veut recopier la liste a dans b, l'opération b = a produit le résultat suivant :
>>> a = [1,2,3]
>>> b = a
>>> a.append(4)
>>> print a,b
[1,2,3,4] [1,2,3,4]


a et b sont en effet des alias, des étiquettes du même objet [1,2,3]. Donc, effectuer une opération sur a revient à effectuer une opération sur b, puisque dans les deux cas on effectue l'opération sur [1,2,3].

Le fils de Dark Vador, le dernier élève de Yoda sont deux périphrases pour désigner Luke Skywalker.

Solution 1.
La copie de listes étant donc une opération très répandue en Python, il existe plusieurs solutions à ce problème de copie. La première consiste à utiliser la fonction list().
>>> a = [1,2,3]
>>> b = list(a)
>>> a.append(4)
>>> print a,b

[1,2,3,4] [1,2,3]

Solution 2.
Utilisation de la fonction copy() du module copy.
>>> import copy
>>> b = copy.copy(a)


Copie de listes de listes.
Examinons le problème en créant une liste de listes, et en la copiant grâce à list().
>>> a = [ [1,2,3] , ["a", "b"] ]
>>> b = list(a)

Rajoutons un élément à a[1].
>>> a[1].append("c")

On peut vérifier que a et b sont deux listes différentes
>>> id(a)
168544588
>>> id(b)
168544876


Affichons a et b :
>>> print a,b
[[1,2,3] , ["a", "b" , "c"]] [[1,2,3] , ["a", "b" , "c"]]


La liste b est elle-aussi modifée !
En effet, le deuxième élément des deux listes est à la même adresse :
>>> id(a[1])
168544492
>>> id(b[1])
168544492


Solution.
La copie de listes de listes se fera grâce à l'instruction deepcopy() du module copy.

mardi 6 janvier 2009

Listes multi-dimensionnelles en Python

En Python, les listes sont l'un des types de données les plus pratiques. Ce sont les équivalents les plus proches des structures de type tableau que l'on rencontre dans d'autres langages.
Donc, à ce titre, on peut également définir des listes multi-dimensionnelles, à 2 dimensions pour commencer.
Script
nb_lignes,nb_cols = 5,4
liste = []
for indl in range(nb_lignes):
.....dummy = [0] * nb_cols
.....liste.append(dummy)
print liste
liste[1][3] = "X"
print liste


Dans l'exemple précédent, on définit une liste liste de 5 lignes par 4 colonnes. L'affichage de la liste avant et après l'insertion du caractère "x" en (1,3) permet d'observer la mise à jour de la liste.

Question
La solution suivante est plus esthétique, mais comporte un piège classique sur la manipulation des objets.
>>> liste = [[0]*nb_lignes] * nb_cols
Quel est le résultat affiché si l'on procède au même remplacement de la position (1,3) ?