Comment supprimer un élément d'une liste par indice ?
J'ai trouvé list.remove()
mais cette méthode parcourt lentement la liste à la recherche d'un élément. par valeur .
Comment supprimer un élément d'une liste par indice ?
J'ai trouvé list.remove()
mais cette méthode parcourt lentement la liste à la recherche d'un élément. par valeur .
Utilice del
et spécifiez l'index de l'élément que vous voulez supprimer :
>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> del a[-1]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8]
Prend également en charge les tranches :
>>> del a[2:4]
>>> a
[0, 1, 4, 5, 6, 7, 8, 9]
Aquí est la section du tutoriel.
N'oubliez pas pop(-1). Oui, c'est la valeur par défaut, mais je la préfère pour ne pas avoir à me rappeler quelle extrémité pop utilise par défaut.
Je ne suis pas d'accord. Si vous connaissez l'étymologie de "pop" pour les programmeurs (c'est l'opération qui supprime et renvoie l'élément top d'une structure de données "pile"), alors pop()
par lui-même est très évident, tandis que pop(-1)
est potentiellement confuse précisément parce que c'est redondant.
Comme d'autres l'ont mentionné, pop et del sont le site des moyens efficaces de supprimer un élément d'un indice donné. Mais juste pour compléter (puisque la même chose peut être faite de plusieurs façons en Python) :
Utilisation de tranches (cela ne permet pas de retirer un élément de la liste originale) :
(C'est également la méthode la moins efficace lorsque l'on travaille avec une liste Python, mais elle peut être utile (mais pas efficace, je le répète) lorsque l'on travaille avec des objets définis par l'utilisateur qui ne supportent pas le pop, mais définissent un __getitem__
) :
>>> a = [1, 2, 3, 4, 5, 6]
>>> index = 3 # Only positive index
>>> a = a[:index] + a[index+1 :]
# a is now [1, 2, 3, 5, 6]
Nota: Veuillez noter que cette méthode ne modifie pas la liste en place comme pop
y del
. Il fait plutôt deux copies de listes (une du début jusqu'à l'index mais sans celui-ci ( a[:index]
) et un après l'index jusqu'au dernier élément ( a[index+1:]
)) et crée un nouvel objet liste en ajoutant les deux. Celui-ci est ensuite réaffecté à la variable liste ( a
). L'ancien objet liste est donc déréférencé et donc récupéré (à condition que l'objet liste original ne soit pas référencé par une autre variable que a).
Cela rend cette méthode très inefficace et peut également produire des effets secondaires indésirables (notamment lorsque d'autres variables pointent vers l'objet liste original qui reste non modifié).
Merci à @MarkDickinson de nous l'avoir signalé ...
Ce site La réponse de Stack Overflow explique le concept de découpage en tranches.
Notez également que cela ne fonctionne qu'avec des indices positifs.
Lors de l'utilisation avec des objets, le __getitem__
doit avoir été définie et, surtout, la méthode __add__
doit avoir été définie pour retourner un objet contenant les éléments des deux opérandes.
En substance, cela fonctionne avec tout objet dont la définition de classe est comme :
class foo(object):
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return foo(self.items[index])
def __add__(self, right):
return foo( self.items + right.items )
Cela fonctionne avec list
qui définit __getitem__
y __add__
méthodes.
Comparaison des trois voies en termes d'efficacité :
Supposons que les éléments suivants soient prédéfinis :
a = range(10)
index = 3
Le site del object[index]
méthode :
C'est de loin la méthode la plus efficace. Elle fonctionne pour tous les objets qui définissent un __del__
méthode.
Le démontage est le suivant :
Code :
def del_method():
global a
global index
del a[index]
Démontage :
10 0 LOAD_GLOBAL 0 (a)
3 LOAD_GLOBAL 1 (index)
6 DELETE_SUBSCR # This is the line that deletes the item
7 LOAD_CONST 0 (None)
10 RETURN_VALUE
None
pop
méthode :
Elle est moins efficace que la méthode del et est utilisée lorsque vous avez besoin de récupérer l'élément supprimé.
Code :
def pop_method():
global a
global index
a.pop(index)
Démontage :
17 0 LOAD_GLOBAL 0 (a)
3 LOAD_ATTR 1 (pop)
6 LOAD_GLOBAL 2 (index)
9 CALL_FUNCTION 1
12 POP_TOP
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
La méthode de découpage et d'ajout.
Le moins efficace.
Code :
def slice_method():
global a
global index
a = a[:index] + a[index+1:]
Démontage :
24 0 LOAD_GLOBAL 0 (a)
3 LOAD_GLOBAL 1 (index)
6 SLICE+2
7 LOAD_GLOBAL 0 (a)
10 LOAD_GLOBAL 1 (index)
13 LOAD_CONST 1 (1)
16 BINARY_ADD
17 SLICE+1
18 BINARY_ADD
19 STORE_GLOBAL 0 (a)
22 LOAD_CONST 0 (None)
25 RETURN_VALUE
None
Note : Dans les trois désassemblages, ignorez les deux dernières lignes qui sont en fait les suivantes return None
. Les deux premières lignes chargent également les valeurs globales. a
y index
.
Votre méthode de découpage ne supprime pas un élément d'une liste : elle crée plutôt un fichier nouveau objet liste contenant tout sauf la ième entrée de la liste originale. La liste d'origine n'est pas modifiée.
@MarkDickinson J'ai modifié la réponse pour clarifier la même chose ... S'il vous plaît laissez-moi savoir si cela semble bon maintenant ?
Oui, c'est un peu mieux. Pardonnez-moi d'être grincheux, mais je crois que ce que j'essaie de dire, c'est que je ne vois pas la valeur de cette réponse : vous donnez deux méthodes qui ont déjà été couvertes de manière adéquate par d'autres réponses, et une troisième méthode (le découpage) qui n'est pas pertinente parce qu'elle ne résout pas réellement le problème posé par le PO.
Si vous voulez supprimer des éléments à des positions spécifiques dans une liste, comme les 2e, 3e et 7e éléments, vous ne pouvez pas utiliser la fonction
del my_list[2]
del my_list[3]
del my_list[7]
Puisque après avoir supprimé le deuxième élément, le troisième élément que vous supprimez est en fait le quatrième élément de la liste originale. Vous pouvez filtrer les 2ème, 3ème et 7ème éléments de la liste originale et obtenir une nouvelle liste, comme ci-dessous :
new_list = [j for i, j in enumerate(my_list) if i not in [2, 3, 7]]
Il répond à mes besoins. J'ai besoin de parcourir une liste et d'en supprimer certains. Avec cette méthode, je vais simplement enregistrer dans une autre liste les index des éléments que je veux supprimer, puis à la fin j'utiliserai la méthode que vous avez donnée pour les supprimer tous en une fois.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
14 votes
@smci : La liste Python est basée sur un tableau : pour supprimer un élément au milieu, vous devez déplacer tous les éléments sur la droite pour supprimer le vide ; c'est pourquoi elle est
O(n)
dans le temps.deque()
fournit des opérations efficaces aux deux extrémités mais ne fournit pas d'insertions, de consultations et de suppressions O(1) au milieu.0 votes
@J.F.Sebastian : implémentation cPython, oui, merci de me corriger. Strictement le spécification linguistique ne spécifie pas comment implémenter la liste, des implémentations alternatives pourraient choisir d'utiliser une liste liée.
0 votes
@smci : aucune implémentation pratique de Python n'utiliserait
O(n)
accès à l'indexa[i]
(en raison des listes de liens). Note : l'implémentation basée sur les tableaux fournitO(1)
accès à l'index.0 votes
@J.F.Sebastian : bien sûr. J'ai simplement noté que la spécification du langage ne le définit pas c'est un problème d'implémentation. (J'ai été surpris de constater que ce n'était pas le cas).
0 votes
@smci si vous ciblez aussi largement, je ne vois pas comment vous pouvez espérer optimiser quoi que ce soit.
0 votes
@NickT : Je mets simplement en garde pour distinguer quand quelque chose est défini par l'implémentation parce qu'il n'est pas défini dans la spécification du langage. C'est exactement ce genre d'hypothèse qui a causé des problèmes majeurs avec l'instabilité du hachage (entre les plateformes) dans la version 2.x. Évidemment, la plupart des implémentations rationnelles de la liste de Python ne choisiraient jamais la liste chaînée puisque nous voulons que les opérations de base soient O(1). C'est tout.
0 votes
En rapport : Différence entre del, remove et pop sur les listes