Lorsque l’on traduit son algorithme en langage informatique et que l’on est concentré sur l’efficacité de son algorithme on peut parfois oublier une spécificité du langage informatique qui fait que votre algorithme ne fonctionnera pas. Et bien évidement, votre premier réflexe est de revoir votre algorithme et de passer des heures et des heures avant de vous rendre enfin compte que finalement, le problème ne viendrait peut être pas de votre algorithme.
Habituellement, en Python, lorsque vous souhaitez copier une variable vous faîtes simplement :
a = 9
b = a
a = 10
print(a)
10
Print(b)
9
Et dans ce cas tout fonctionne parfaitement. Cependant, tout ne fonctionne pas exatement de la même façon pour tous les types de variables. Exemple :
a = [9]
b = a
a[0] = 10
print(a)
[10]
print(b)
[10]
Comme vous pouvez le voir assigner à une nouvelle liste une liste déjà existante ne la duplique pas mais donne tout simplement une deuxième porte d’accès à cette liste. Python réagit comme ça afin de limiter l’impacte mémoire du programme.
Si vous souhaitez réellement dupliquer une liste, deux solutions s’offrent à vous. Tout d’abord, l’utilisation d’un slice :
a = [9]
b = a[:]
a[0] = 10
print(a)
[10]
print(b)
[9]
Je trouve cette méthode moins jolie. Je préfère utiliser la deuxième solution que je trouve plus pythonique, à savoir :
a = [9]
b = list(a)
a[0] = 10
print(a)
[10]
print(b)
[9]
Et voilà, vous vous retrouvez avec deux listes complètement distinctes.
Mais voilà, en général ça marche bien. Mais là hier, ça ne voulait rien savoir, ça ne marchait pas. J’ai passé plus de 3 heures à remettre en question mon algorithme qui, une fois en Python, ne voulait pas faire ce qu’il était sensé faire. Et puis, en regardant de plus près, je vois ça :
a = [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
b = list(a)
Je voulais dupliquer une liste de dimension supérieure à 1, mais Python lui, ne le voyait pas de cette façon là. Et pour cause… List() et [:] ne sont pas récursifs. Ce qui veut dire qu’ils ne vont dupliquer que la liste de premier niveau et pas les listes qu’elle peut elle-même contenir. Tout ça pour ça… 3 heures…
Et bien la solution est simple, il est nécessaire de passer par la fonction deepcopy(). Cette fonction permet de copier tout object et les objects qu’il peut imbriquer.
from copy import deepcopy
a = [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
b = deepcopy(a)
Et voilà, nous nous retrouvons bien avec deux listes bien distinctes mais identiques.
CopyLeft - 2013-17 - Toutes gauches réservées - Licence CC-BY
Valide xHtml 1.0 STRICT | Fièrement propulsé par PluXml | 0.016s | 144082 vues
2 commentaires
#1 lundi 29 octobre 2018 à 08:20 a dit :
Hey I know this is off topic but I was wondering if you
knew of any widgets I could add to my blog that automatically tweet my newest twitter updates.
I've been looking for a plug-in like this for quite some time and was hoping
maybe you would have some experience with something like this.
Please let me know if you run into anything. I truly enjoy
reading your blog and I look forward to your new updates.
#2 mercredi 02 janvier 2019 à 22:34 a dit :
Generally I do not learn post on blogs, however I would like to say that
this write-up very compelled me to try and do so!
Your writing taste has been surprised me. Thanks, quite great post.
Fil RSS des commentaires de cet article