Comment supprimer un élément spécifique d'un tableau à l'aide de python

138

Je veux écrire quelque chose qui supprime un élément spécifique d'un tableau. Je sais que je dois forparcourir le tableau pour trouver l'élément qui correspond au contenu.

Disons que j'ai un tableau d'e-mails et que je veux me débarrasser de l'élément qui correspond à une chaîne d'e-mail.

En fait, j'aimerais utiliser la structure de la boucle for car je dois également utiliser le même index pour d'autres tableaux.

Voici le code que j'ai:

for index, item in emails:
    if emails[index] == '[email protected]':
         emails.pop(index)
         otherarray.pop(index)
Locoboy
la source
6
Cherchez-vous list.remove(x)?
Jacob
pas assez. Je voudrais utiliser la boucle for afin de pouvoir réutiliser l'index
locoboy
4
Vous ne devriez pas changer la liste en l'itérant.
Jacob
pourquoi ne devrais-je pas faire ça? aussi ça ne marche pas pour moi.
locoboy

Réponses:

200

Vous n'avez pas besoin d'itérer le tableau. Juste:

>>> x = ['[email protected]', '[email protected]']
>>> x
['[email protected]', '[email protected]']
>>> x.remove('[email protected]')
>>> x
['[email protected]']

Cela supprimera la première occurrence qui correspond à la chaîne.

EDIT: Après votre modification, vous n'avez toujours pas besoin de répéter. Faites simplement:

index = initial_list.index(item1)
del initial_list[index]
del other_list[index]
Bogdan
la source
1
voir ci-dessus je voudrais utiliser la boucle for pour réutiliser le même index
locoboy
J'ai modifié ma réponse. Toujours pas besoin de boucle.
Bogdan
1
Comment vérifiez-vous d'abord que l'élément existe dans la liste_initial? Il pourrait y avoir un cas où il n'existe pas et vous n'aurez pas à le supprimer.
locoboy
17

Utiliser filter()et lambdafournirait une méthode claire et concise pour supprimer les valeurs indésirables:

newEmails = list(filter(lambda x : x != '[email protected]', emails))

Cela ne modifie pas les e-mails. Il crée la nouvelle liste newEmails contenant uniquement les éléments pour lesquels la fonction anonyme a renvoyé True.

Ron Kalian
la source
5

Votre boucle for n'est pas correcte, si vous avez besoin de l'index dans la boucle for, utilisez:

for index, item in enumerate(emails):
    # whatever (but you can't remove element while iterating)

Dans votre cas, la solution Bogdan est correcte, mais votre choix de structure de données n'est pas si bon. Il est maladroit de devoir maintenir ces deux listes avec des données de l'une liées à des données de l'autre au même index.

Une liste de tupple (e-mail, autres données) peut être meilleure, ou un dict avec e-mail comme clé.

MatthieuW
la source
4

La bonne façon de faire est d'utiliser zip()et une expression de compréhension de liste / générateur:

filtered = (
    (email, other) 
        for email, other in zip(emails, other_list) 
            if email == '[email protected]')

new_emails, new_other_list = zip(*filtered)

Aussi, si vous n'utilisez pas array.array()ou numpy.array(), alors vous utilisez probablement []ou list(), qui vous donne des listes, pas des tableaux. Pas la même chose.

pillmuncher
la source
1
Personne ne sait en quoi c'est "sain" par rapport à la réponse de @ Bogdan, qui est beaucoup, beaucoup plus propre.
Jordan Lapp du
Merci de souligner que les tableaux ne sont pas les mêmes que les listes. La réponse sélectionnée ne fonctionne pas sur les tableaux dans 2.7.
EL_DON
2

Il existe une solution alternative à ce problème qui traite également des correspondances en double.

Nous commençons avec 2 listes de longueur égale: emails, otherarray. L'objectif est de supprimer des éléments des deux listes pour chaque index iemails[i] == '[email protected]'.

Ceci peut être réalisé en utilisant une compréhension de liste puis en le fractionnant via zip:

emails = ['[email protected]', '[email protected]', '[email protected]']
otherarray = ['some', 'other', 'details']

from operator import itemgetter

res = [(i, j) for i, j in zip(emails, otherarray) if i!= '[email protected]']
emails, otherarray = map(list, map(itemgetter(0, 1), zip(*res)))

print(emails)      # ['[email protected]', '[email protected]']
print(otherarray)  # ['some', 'details']
jpp
la source