Les autres réponses sont à la recherche à partir d'un point de vue technique (c'est à dire quelle est la meilleure façon de modifier une liste), mais je dirais que le (beaucoup) plus importante raison pour laquelle les gens sont ce qui suggère par exemple de découpage, c'est qu'il ne doit pas modifier la liste d'origine.
La raison pour cela est que généralement, la liste est venu de quelque part. Si vous le modifiez, vous pouvez unknowningly cause d'une très mauvaise et difficile à détecter les effets secondaires, qui peuvent causer des bugs ailleurs dans le programme. Ou même si vous n'avez pas à cause d'un bug immédiatement, vous allez rendre votre programme plus difficile à comprendre et à raisonner et à déboguer.
Par exemple, les interprétations de la liste/générateur d'expressions de nice en qui ils n'ont jamais muter la "source" de la liste, ils sont passés:
[x for x in lst if x != "foo"] # creates a new list
(x for x in lst if x != "foo") # creates a lazy filtered stream
Bien sûr, cela est souvent plus cher (de mémoire sage), parce qu'il crée une nouvelle liste, mais un programme qui utilise cette approche est mathématiquement plus pure et la plus facile de raisonner sur. Et avec lazy listes (générateurs et générateur d'expressions), même la surcharge de la mémoire disparaît, et les calculs sont exécutés uniquement sur demande; voir http://www.dabeaz.com/generators/ pour passer une excellente introduction. Et vous ne devriez pas trop penser à l'optimisation lors de la conception de votre programme (voir http://programmers.stackexchange.com/questions/80084/is-premature-optimization-really-the-root-of-all-evil). Aussi, la suppression d'un élément d'une liste est assez cher, sauf si c'est une liste chaînée (qui Python list
ne l'est pas; pour la liste, voir collections.deque
).
En fait, sans effets secondaires fonctions et immuable structures de données sont à la base de la Programmation Fonctionnelle, un très puissant paradigme de programmation.
Toutefois, dans certaines circonstances, il est OK pour modifier une structure de données en place (même en FP, si le langage le permet), comme lorsqu'elle est localement créé un, ou copié à partir de l'entrée de la fonction:
def sorted(lst):
ret = list(lst) # make a copy
# mutate ret
return ret
- cette fonction semble être une pure fonction de l'extérieur, car il ne modifie pas ses entrées (et aussi ne dépend que de ses arguments et rien d'autre (c'est à dire qu'il n'a pas de (global) de l'état), qui est une autre condition pour que quelque chose soit une Pure Fonction).
Donc, tant que vous savez ce que vous faites, del
n est pas mauvais; mais l'utilisation de toute sorte de données de mutation avec une extrême prudence et seulement quand vous avez. Toujours commencer avec un peut de moins en moins efficace, mais plus correct et mathématiquement le code élégant.
...et d'apprendre la Programmation Fonctionnelle :)
P. S. remarque qu' del
peut également être utilisé pour supprimer des variables locales et donc d'éliminer les références à des objets en mémoire, ce qui est souvent utile pour quelle que soit la GC à des fins connexes.
La réponse à votre deuxième question:
Quant à la deuxième partie de votre question sur del
suppression des objets complètement - ce n'est pas le cas: en fait en Python, il n'est même pas possible de dire à l'interprète/VM pour supprimer un objet de mémoire, parce que Python est l'un des ordures collectées langue (comme Java, C#, Ruby, Haskell, etc) et c'est l'exécution qui décide ce qu'il faut supprimer et quand.
Au lieu de cela, ce del
n'lorsqu'il est appelé sur une variable (par opposition à une clé de dictionnaire ou un élément de liste) comme ceci:
del a
c'est qu'il seulement supprime le local (ou global) de la variable et non pas ce que la variable de points (chaque variable en Python est titulaire d'un pointeur/référence à son contenu, pas le contenu lui-même). En fait, depuis que les habitants et les variables globales sont stockés sous forme de dictionnaire sous le capot (voir locals()
et globals()
), del a
est équivalent à:
del locals()['a']
ou del globals()['a']
lorsqu'il est appliqué à une échelle mondiale.
donc, si vous avez:
a = []
b = a
vous faites une liste, enregistrer une référence en a
, puis de faire une copie de celui de référence et de les stocker en b
sans copier/contact de la liste de l'objet lui-même. Par conséquent, ces deux appels d'affecter un seul et même objet:
a.append(1)
b.append(2)
# the list will be [1, 2]
alors que la suppression d' b
n'est en aucune façon liée à toucher ce qu' b
points de:
a = []
b = a
del b
# a is still untouched and points to a list
Aussi, même lorsque vous appelez del
sur un attribut de l'objet (par exemple, del self.a
), vous êtes toujours en fait de la modification d'un dictionnaire, self.__dict__
juste comme vous êtes en train de modifier locals()
/globals()
lorsque vous effectuez del a
.
P. S. comme Sven Marcnah a souligné que l' del locals()['a']
n'a pas fait de supprimer la variable locale a
lorsque l'intérieur d'une fonction, ce qui est correct. Ceci est probablement dû à l' locals()
retour une copie du réel habitants. Toutefois, la réponse est toujours valide.