web-dev-qa-db-fra.com

Supprimer toutes les occurrences d'une valeur d'une liste?

En Python, remove() supprimera la première occurrence de valeur dans une liste.

Comment supprimer toutes les occurrences d'une valeur d'une liste, sans trier la liste?

C'est ce que j'ai en tête.

>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> def remove_values_from_list(the_list, val):
        while val in the_list:
            the_list.remove(val)
>>> remove_values_from_list(x, 2)
>>> x
[1, 3, 4, 3]
281
riza

Approche fonctionnelle:

2.x

>>> x = [1,2,3,2,2,2,3,4]
>>> filter(lambda a: a != 2, x)
[1, 3, 3, 4]

3.x

>>> x = [1,2,3,2,2,2,3,4]
>>> list(filter((2).__ne__, x))
[1, 3, 3, 4]

ou 

>>> x = [1,2,3,2,2,2,3,4]
>>> list(filter(lambda a: a != 2, x))
[1, 3, 3, 4]
389
Mark Rushakoff

Vous pouvez utiliser une compréhension de liste:

def remove_values_from_list(the_list, val):
   return [value for value in the_list if value != val]

x = [1, 2, 3, 4, 2, 2, 3]
x = remove_values_from_list(x, 2)
print x
# [1, 3, 4, 3]
173
mhawke

Vous pouvez utiliser l'affectation de tranche si la liste d'origine doit être modifiée, tout en utilisant une compréhension de liste efficace (ou une expression génératrice).

>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> x[:] = (value for value in x if value != 2)
>>> x
[1, 3, 4, 3]
88
A. Coady

Répéter la solution du premier message de manière plus abstraite:

>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> while 2 in x: x.remove(2)
>>> x
[1, 3, 4, 3]
30
funk

Voir les solutions simples

Solution 1:

>>> [i for i in x if i != 2]

Cela retournera une liste contenant tous les éléments de x sans 2

Solution 2:

>>> while 2 in x : x.remove(2)
12
Shameem

Toutes les réponses ci-dessus (à l'exception de Martin Andersson) créent une nouvelle liste sans les éléments souhaités, au lieu de les supprimer de la liste d'origine. 

>>> import random, timeit
>>> a = list(range(5)) * 1000
>>> random.shuffle(a)

>>> b = a
>>> print(b is a)
True

>>> b = [x for x in b if x != 0]
>>> print(b is a)
False
>>> b.count(0)
0
>>> a.count(0)
1000

>>> b = a
>>> b = filter(lambda a: a != 2, x)
>>> print(b is a)
False

Cela peut être important si vous avez d'autres références à la liste.

Pour modifier la liste en place, utilisez une méthode comme celle-ci.

>>> def removeall_inplace(x, l):
...     for _ in xrange(l.count(x)):
...         l.remove(x)
...
>>> removeall_inplace(0, b)
>>> b is a
True
>>> a.count(0)
0

En ce qui concerne la vitesse, les résultats sur mon ordinateur portable sont (tous sur une liste de 5000 entrées avec 1000 entrées supprimées)

  • Compréhension de liste - ~ 400us
  • Filtre - ~ 900us
  • Boucle .remove () - 50ms

Donc, la boucle .remove est environ 100x plus lente ... Hmmm, une approche différente est peut-être nécessaire. Le plus rapide que j'ai trouvé utilise la compréhension de liste, mais remplace ensuite le contenu de la liste d'origine.

>>> def removeall_replace(x, l):
....    t = [y for y in l if y != x]
....    del l[:]
....    l.extend(t)
  • removeall_replace () - 450us
8
Paul S

tu peux le faire

while 2 in x:   
    x.remove(2)
6
Amr

Au prix de la lisibilité, je pense que cette version est un peu plus rapide car elle n’oblige pas à réexaminer la liste, ce qui signifie que faire exactement le même travail supprime:

x = [1, 2, 3, 4, 2, 2, 3]
def remove_values_from_list(the_list, val):
    for i in range(the_list.count(val)):
        the_list.remove(val)

remove_values_from_list(x, 2)

print(x)
5
Martin Andersson

Pour supprimer toutes les occurrences en double et en laisser une dans la liste:

test = [1, 1, 2, 3]

newlist = list(set(test))

print newlist

[1, 2, 3]

Voici la fonction que j'ai utilisée pour Project Euler:

def removeOccurrences(e):
  return list(set(e))
3
Jared Burrows

Je crois que c'est probablement plus rapide que tout autre moyen si vous ne vous souciez pas de l'ordre des listes, si vous vous occupez de l'ordre final, stockez les index de l'original et par la suite.

category_ids.sort()
ones_last_index = category_ids.count('1')
del category_ids[0:ones_last_index]
2
Michael Clemmons

Approche Numpy et timings sur une liste/tableau avec 1.000.000 éléments:

Horaires:

In [10]: a.shape
Out[10]: (1000000,)

In [13]: len(lst)
Out[13]: 1000000

In [18]: %timeit a[a != 2]
100 loops, best of 3: 2.94 ms per loop

In [19]: %timeit [x for x in lst if x != 2]
10 loops, best of 3: 79.7 ms per loop

Conclusion: numpy est 27 fois plus rapide (sur mon cahier) par rapport à la compréhension de la liste

PS si vous souhaitez convertir votre liste Python régulière lst en tableau numpy:

arr = np.array(lst)

Installer:

import numpy as np
a = np.random.randint(0, 1000, 10**6)

In [10]: a.shape
Out[10]: (1000000,)

In [12]: lst = a.tolist()

In [13]: len(lst)
Out[13]: 1000000

Vérifier:

In [14]: a[a != 2].shape
Out[14]: (998949,)

In [15]: len([x for x in lst if x != 2])
Out[15]: 998949
2
MaxU
for i in range(a.count(' ')):
    a.remove(' ')

Beaucoup plus simple je crois.

1
marco

Première solution, en utilisant un filtre.
Deuxième solution, utilisant la compréhension par liste.

#If we want to remove all 2.
ls = [2, 2, 3, 4, 5, 6, 7, 8, 2, 3, 4, 6, 2]

# 1-filter takes two arguments(condition,sequence)
   ls = list(filter(lambda x: x != 2, ls))

# 2-list comprehension
   ls = [x for x in ls if x != 2]
1
Maz1978

Supprimer toutes les occurrences d'une valeur d'une liste Python

lists = [6.9,7,8.9,3,5,4.9,1,2.9,7,9,12.9,10.9,11,7]
def remove_values_from_list():
    for list in lists:
      if(list!=7):
         print(list)
remove_values_from_list()

Résultat: 6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11

Alternativement

lists = [6.9,7,8.9,3,5,4.9,1,2.9,7,9,12.9,10.9,11,7]
def remove_values_from_list(remove):
    for list in lists:
      if(list!=remove):
        print(list)
remove_values_from_list(7)

Résultat: 6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11

1
rafiqul786

Est-ce que cela modifie la liste?

>>> x=[1,2,3,4,5,6,7,8]
>>> x
[1, 2, 3, 4, 5, 6, 7, 8]
>>> x = [val for val in x if val not in [2,3,4]]
>>> x
[1, 5, 6, 7, 8]
1
Stephen Boston
a = [1, 2, 2, 3, 1]
to_remove = 1
a = [i for i in a if i != to_remove]
print(a)

Peut-être pas le plus pythonique mais toujours le plus facile pour moi haha

1
Ankit Sharma

Quel est le problème avec:

Moteur = ['1', '2', '2'] Pour i dans le moteur: Si i! = '2': Imprimer (i) Imprimer (moteur)

Utiliser l'anaconda 

0
code developer

Laisser

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

La solution la plus simple et la plus efficace, telle que déjà publiée auparavant, est

>>> x[:] = [v for v in x if v != 2]
>>> x
[1, 3, 4, 3]

Une autre possibilité qui devrait utiliser moins de mémoire mais être plus lent est

>>> for i in range(len(x) - 1, -1, -1):
        if x[i] == 2:
            x.pop(i)  # takes time ~ len(x) - i
>>> x
[1, 3, 4, 3]

Résultats de chronométrage pour des listes de longueur 1000 et 100000 avec 10% entrées correspondantes: 0,16 vs 0,25 ms et 23 vs 123 ms.

 Timing with length 1000

 Timing with length 100000

0
jolvi
hello =  ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
#chech every item for a match
for item in range(len(hello)-1):
     if hello[item] == ' ': 
#if there is a match, rebuild the list with the list before the item + the list after the item
         hello = hello[:item] + hello [item + 1:]
print hello

['Bonjour le monde']

0
SaNaMeDiO

Si vous n'avez pas intégré filter ou si vous ne voulez pas utiliser d'espace supplémentaire et que vous avez besoin d'une solution linéaire ...

def remove_all(A, v):
    k = 0
    n = len(A)
    for i in range(n):
        if A[i] !=  v:
            A[k] = A[i]
            k += 1

    A = A[:k]
0
cipher

Je viens de faire cela pour une liste. Je ne suis qu'un débutant. Un programmeur légèrement plus avancé peut sûrement écrire une fonction comme celle-ci.

for i in range(len(spam)):
    spam.remove('cat')
    if 'cat' not in spam:
         print('All instances of ' + 'cat ' + 'have been removed')
         break
0
Asir Ajmal