Comment supprimer un élément d'une liste par index

1507

Comment supprimer un élément d'une liste par index en Python?

J'ai trouvé la list.removeméthode, mais dis que je veux supprimer le dernier élément, comment faire? Il semble que la suppression par défaut recherche dans la liste, mais je ne veux pas effectuer de recherche.

Joan Venge
la source
10
@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 l'écart, c'est pourquoi il est O(n)en fonctionnement temporel. deque()fournit des opérations efficaces aux deux extrémités mais ne fournit pas d'insertions / recherches / suppressions O (1) au milieu.
jfs
@JFSebastian: implémentation de cPython, oui, merci de m'avoir corrigé. Strictement, la spécification de langue ne spécifie pas comment implémenter la liste, des implémentations alternatives pourraient choisir d'utiliser une liste liée.
smci
@smci: aucune implémentation Python pratique n'utiliserait l' O(n)accès à l'index a[i](en raison des listes chaînées). Remarque: l'implémentation basée sur un tableau fournit O(1)un accès à l'index.
jfs
@JFSebastian: bien sûr. J'ai simplement noté que la spécification de langue ne définit pas cela , c'est un problème d'implémentation. (J'ai été surpris de constater que ce n'était pas le cas.)
smci
@smci si vous ciblez cela de manière large, je ne sais pas comment vous pouvez espérer optimiser quoi que ce soit.
Nick T

Réponses:

1742

Utilisez delet spécifiez l'index de l'élément que vous souhaitez 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]

Voici la section du tutoriel.

Neil Chowdhury
la source
53
Merci, quelle est la différence entre pop et del?
Joan Venge
37
del est surchargé. Par exemple, del a supprime toute la liste
Brian R. Bondy
34
un autre exemple del a [2: 4], supprime les éléments 2 et 3
Brian R. Bondy
307
pop () renvoie l'élément que vous souhaitez supprimer. del supprime juste est.
13
Je ne vois pas de preuve de "liste chaînée" là-bas. Regardez svn.python.org/projects/python/trunk/Objects/listobject.c comment PyList_GetItem()retourne essentiellement ((PyListObject *)op) -> ob_item[i];- le ie élément d'un tableau.
glglgl
649

Vous voulez probablement pop:

a = ['a', 'b', 'c', 'd']
a.pop(1)

# now a is ['a', 'c', 'd']

Par défaut, popsans aucun argument supprime le dernier élément:

a = ['a', 'b', 'c', 'd']
a.pop()

# now a is ['a', 'b', 'c']
Jarret Hardie
la source
105
N'oubliez pas la pop (-1). Oui, c'est la valeur par défaut, mais je la préfère donc je n'ai pas à me rappeler quelle fin pop utilise par défaut.
S.Lott
282
Je ne suis pas d'accord. Si vous connaissez l'étymologie du programmeur de «pop» (c'est l'opération qui supprime et renvoie le haut d'une structure de données «pile»), alors pop()en soi est très évidente, alors qu'elle pop(-1)est potentiellement déroutante précisément parce qu'elle est redondante.
coredumperror
a.pop (-1) pour supprimer le dernier?
zx1986
14
@ zx1986 a popdans la plupart des langages de programmation supprime généralement le dernier élément, comme il le fait en Python. Donc, si vous spécifiez -1 ou rien, c'est la même chose.
Pascal
30
Soit dit en passant, pop()retourne tout élément qu'il a supprimé.
Bob Stein
136

Comme d'autres mentionnés, pop et del sont les moyens efficaces de supprimer un élément d'index donné. Pourtant, juste pour le plaisir de terminer (puisque la même chose peut être faite de plusieurs façons en Python):

Utilisation de tranches (cela ne supprime pas en place l'élément de la liste d'origine):

(Ce sera également la méthode la moins efficace lorsque vous travaillerez avec une liste Python, mais cela pourrait être utile (mais pas efficace, je le répète) lorsque vous travaillez avec des objets définis par l'utilisateur qui ne prennent pas en charge la pop, mais définissez néanmoins a __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]

Remarque: Veuillez noter que cette méthode ne modifie pas la liste en place comme popet del. Il crée à la place deux copies de listes (une depuis le début jusqu'à l'index mais sans lui ( a[:index]) et une après l'index jusqu'au dernier élément ( a[index+1:])) et crée un nouvel objet liste en ajoutant les deux. Il est ensuite réaffecté à la variable de liste ( a). L'ancien objet liste est donc déréférencé et donc récupéré (à condition que l'objet liste d'origine ne soit référencé par aucune variable autre que a).

Cela rend cette méthode très inefficace et peut également produire des effets secondaires indésirables (en particulier lorsque d'autres variables pointent vers l'objet de liste d'origine qui reste non modifié).

Merci à @MarkDickinson de l'avoir signalé ...

Cette réponse Stack Overflow explique le concept de découpage.

Notez également que cela ne fonctionne qu'avec des indices positifs.

Lors de l'utilisation avec des objets, la __getitem__méthode doit avoir été définie et, plus important encore, la __add__méthode doit avoir été définie pour renvoyer un objet contenant des é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 listqui définit __getitem__et les __add__méthodes.

Comparaison des trois voies en termes d'efficacité:

Supposons que ce qui suit est prédéfini:

a = range(10)
index = 3

La del object[index]méthode:

De loin la méthode la plus efficace. Il fonctionne avec tous les objets qui définissent une __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 d'obtenir 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 tranche et 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

Remarque: Dans les trois démontages, ignorez les deux dernières lignes qui le sont essentiellement return None. Les deux premières lignes chargent également les valeurs globales aet index.

Raghav RV
la source
4
Votre méthode de découpage ne supprime pas un élément d'une liste: à la place, elle crée un nouvel objet de liste contenant tout sauf la ième entrée de la liste d'origine. La liste d'origine n'est pas modifiée.
Mark Dickinson
@MarkDickinson Ont édité la réponse pour clarifier la même chose ... S'il vous plaît, faites-moi savoir si cela semble bon maintenant?
Raghav RV
6
Peut-être que la réponse n'était pas entièrement sur le sujet, mais la méthode d'indexation est utile si vous devez omettre un élément d'un objet immuable, tel qu'un tuple. pop () et del () ne fonctionneront pas dans ce cas.
Caleb
6
@ rvraghav93 sur toutes les méthodes présentées pendant tout le post, le a = a[:index] + a[index+1 :]-trick était le plus savant en ce qui concerne les énormes listes. Toutes les autres méthodes se sont retrouvées dans une impasse. Merci beaucoup
user3085931
3
En effet Mark, tu es grincheux. Cette réponse est celle que j'ai préférée car elle était vraiment pédagogique. J'ai appris le plus de cette réponse et des détails de démontage qui ont été fournis et de l'impact sur la performance. De plus, la méthode de découpage, oui, créez un autre objet, mais maintenant il est spécifié et parfois c'est aussi ce dont vous avez besoin.
Yohan Obadia
52

popest également utile pour supprimer et conserver un élément d'une liste. Où deljette réellement l'élément.

>>> x = [1, 2, 3, 4]

>>> p = x.pop(1)
>>> p
    2
codeur de bateau
la source
24

Si vous souhaitez supprimer l'élément de position spécifique dans une liste, comme les 2ème, 3ème et 7ème. tu ne peux pas utiliser

del my_list[2]
del my_list[3]
del my_list[7]

Étant donné qu'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 d'origine. Vous pouvez filtrer les 2e, 3e et 7e éléments de la liste d'origine 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]]
xiaojia zhang
la source
19

Cela dépend de ce que vous voulez faire.

Si vous souhaitez renvoyer l'élément que vous avez supprimé, utilisez pop():

>>> l = [1, 2, 3, 4, 5]
>>> l.pop(2)
3
>>> l
[1, 2, 4, 5]

Cependant, si vous souhaitez simplement supprimer un élément, utilisez del:

>>> l = [1, 2, 3, 4, 5]
>>> del l[2]
>>> l
[1, 2, 4, 5]

En outre, delvous permet d'utiliser des tranches (par exemple del[2:]).

Neil Chowdhury
la source
18

En général, j'utilise la méthode suivante:

>>> myList = [10,20,30,40,50]
>>> rmovIndxNo = 3
>>> del myList[rmovIndxNo]
>>> myList
[10, 20, 30, 50]
Mayur Koshti
la source
15

Encore une autre façon de supprimer un élément (s) d'une liste par index.

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# remove the element at index 3
a[3:4] = []
# a is now [0, 1, 2, 4, 5, 6, 7, 8, 9]

# remove the elements from index 3 to index 6
a[3:7] = []
# a is now [0, 1, 2, 7, 8, 9]

a [x: y] pointe vers les éléments de l'index xau y-1. Lorsque nous déclarons cette partie de la liste comme une liste vide ( []), ces éléments sont supprimés.

Andreas Chatzivasileiadis
la source
14

Vous pouvez simplement rechercher l'élément que vous souhaitez supprimer. C'est vraiment simple. Exemple:

    letters = ["a", "b", "c", "d", "e"]
    letters.remove(letters[1])
    print(*letters) # Used with a * to make it unpack you don't have to (Python 3.x or newer)

Sortie: acde

SollyBunny
la source
6
J'aime cette solution, mais bien sûr, elle suppose que votre liste n'a pas de doublons.
tommy.carstensen
11

Utilisez le code suivant pour supprimer l'élément de la liste:

list = [1, 2, 3, 4]
list.remove(1)
print(list)

output = [2, 3, 4]

Si vous souhaitez supprimer les données d'élément d'index de la liste, utilisez:

list = [1, 2, 3, 4]
list.remove(list[2])
print(list)
output : [1, 2, 4]
jitsm555
la source
2
Livré avec la mise en garde que votre liste ne peut pas contenir de doublons.
tommy.carstensen
3
Il ne s'agit pas de supprimer par index, mais de supprimer par correspondance de valeur. Cela peut être une information précieuse pour certaines personnes qui visitent ici, mais n'essaie pas du tout de répondre à la question des PO.
Anthon
8

Comme mentionné précédemment, la meilleure pratique est del (); ou pop () si vous avez besoin de connaître la valeur.

Une autre solution consiste à ré-empiler uniquement les éléments souhaités:

    a = ['a', 'b', 'c', 'd'] 

    def remove_element(list_,index_):
        clipboard = []
        for i in range(len(list_)):
            if i is not index_:
                clipboard.append(list_[i])
        return clipboard

    print(remove_element(a,2))

    >> ['a', 'b', 'd']

eta: hmm ... ne fonctionnera pas sur les valeurs d'index négatives, réfléchira et mettra à jour

Je suppose

if index_<0:index_=len(list_)+index_

le réparerait ... mais soudain, cette idée semble très fragile. Expérience de pensée intéressante cependant. Il semble qu'il devrait y avoir un moyen «approprié» de le faire avec la compréhension append () / list.

méditer

litepresence
la source
1
Quelle version de Python a une fonction del()? Pour cette fonction, vous fournissez la liste comme premier argument de cette fonction, puis l'index, ou l'index d'abord, puis la liste? Renvoie-t-il l'argument de liste sans l'élément ou effectue-t-il la suppression sur place? Je connais la deldéclaration, mais pas une fonction du même nom.
Anthon
8

Il ne semble pas que vous travailliez avec une liste de listes, donc je serai bref. Vous voulez utiliser pop car il supprimera les éléments et non les éléments qui sont des listes, vous devez utiliser del pour cela. Pour appeler le dernier élément en python c'est "-1"

>>> test = ['item1', 'item2']
>>> test.pop(-1)
'item2'
>>> test
['item1']
Mo Ali
la source
1
pop()et les deldeux suppriment un élément à l'index fourni, que cet élément soit lui-même une liste ou non. a = [1, [2, 3], 4]; del a[1]; b = [1, [2, 3], 4]; b.pop(1); assert a == b
Anthon
8

l - liste de valeurs; nous devons supprimer les index de la liste inds2rem .

l = range(20)
inds2rem = [2,5,1,7]
map(lambda x: l.pop(x), sorted(inds2rem, key = lambda x:-x))

>>> l
[0, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Jo Ja
la source
ne fonctionne pas, la réponse est <map at 0x7f4d54109a58>. et l est gamme (0,20)
Hitesh
7

Utilisez la fonction "del" :

del listName[-N]

Par exemple, si vous souhaitez supprimer les 3 derniers éléments, votre code doit être:

del listName[-3:]

Par exemple, si vous souhaitez supprimer les 8 derniers éléments, votre code doit être:

del listName[-8:]
lloydyu24
la source
2
delest une déclaration . Si c'était une fonction, il faudrait écriredel(listame[-N])
Anthon
7

Il a déjà été mentionné comment supprimer un seul élément d'une liste et quels sont les avantages des différentes méthodes. Notez, cependant, que la suppression de plusieurs éléments peut entraîner des erreurs:

>>> l = [0,1,2,3,4,5,6,7,8,9]
>>> indices=[3,7]
>>> for i in indices:
...     del l[i]
... 
>>> l
[0, 1, 2, 4, 5, 6, 7, 9]

Les éléments 3 et 8 (et non 3 et 7) de la liste d'origine ont été supprimés (car la liste a été raccourcie pendant la boucle), ce qui n'était peut-être pas l'intention. Si vous souhaitez supprimer plusieurs index en toute sécurité, vous devez d'abord supprimer les éléments avec l'index le plus élevé, par exemple comme ceci:

>>> l = [0,1,2,3,4,5,6,7,8,9]
>>> indices=[3,7]
>>> for i in sorted(indices, reverse=True):
...     del l[i]
... 
>>> l
[0, 1, 2, 4, 5, 6, 8, 9]
Kopfgeldjaeger
la source
4

Ou si plusieurs index doivent être supprimés:

print([v for i,v in enumerate(your_list) if i not in list_of_unwanted_indexes])

Bien sûr, cela pourrait également faire:

print([v for i,v in enumerate(your_list) if i != unwanted_index])
U10-Forward
la source
1
Pourquoi ne triez-vous pas simplement la liste des indices dans l'ordre inverse, puis les supprimez-les un par un? De cette façon, vous n'avez pas à faire une nouvelle liste.
Anthon
3

Vous pouvez utiliser del ou pop pour supprimer l'élément de la liste en fonction de l'index. Pop imprimera le membre qu'il supprime de la liste, tandis que la liste supprimera ce membre sans l'imprimer.

>>> a=[1,2,3,4,5]
>>> del a[1]
>>> a
[1, 3, 4, 5]
>>> a.pop(1)
 3
>>> a
[1, 4, 5]
>>> 
Aashutosh jha
la source
3

On peut utiliser del ou pop, mais je préfère del, car vous pouvez spécifier l'index et les tranches, donnant à l'utilisateur plus de contrôle sur les données.

Par exemple, en commençant par la liste affichée, on peut supprimer son dernier élément avec delcomme tranche, puis on peut supprimer le dernier élément du résultat en utilisant pop.

>>> l = [1,2,3,4,5]
>>> del l[-1:]
>>> l
[1, 2, 3, 4]
>>> l.pop(-1)
4
>>> l
[1, 2, 3]
pyman
la source