it-swarm.com.de

Alle Vorkommen eines Wertes aus einer Liste entfernen?

In Python entfernt remove() das erste Vorkommen eines Wertes in einer Liste.

Wie entferne ich alle Vorkommen eines Wertes aus einer Liste, ohne die Liste zu sortieren?

Daran habe ich gedacht.

>>> 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

Funktionaler Ansatz:

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]

oder 

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

Sie können ein Listenverständnis verwenden:

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

Sie können die Slice-Zuordnung verwenden, wenn die ursprüngliche Liste geändert werden muss und gleichzeitig ein effizientes Listenverständnis (oder Generatorausdruck) verwendet wird.

>>> 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

Die Lösung des ersten Beitrags auf eine abstraktere Weise wiederholen:

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

Sehen Sie sich die einfachen Lösungen an

Lösung 1:

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

Dadurch wird eine Liste mit allen Elementen von x ohne 2.__ zurückgegeben.

Lösung 2:

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

Alle Antworten (außer Martin Anderssons) erstellen eine neue Liste ohne die gewünschten Elemente, anstatt die Elemente aus der ursprünglichen Liste zu entfernen. 

>>> 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

Dies kann wichtig sein, wenn andere Verweise auf die Liste vorhanden sind.

Verwenden Sie eine Methode wie diese, um die Liste zu ändern

>>> 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

Was die Geschwindigkeit angeht, werden die Ergebnisse auf meinem Laptop angezeigt (alle auf einer Liste mit 5000 Einträgen, wobei 1000 Einträge entfernt wurden).

  • Listenverständnis - ~ 400us
  • Filter ~ 900us
  • .remove () Schleife - 50ms

Die .remove-Schleife ist also etwa 100x langsamer ... Hmmm, vielleicht ist ein anderer Ansatz erforderlich. Die schnellste, die ich gefunden habe, ist die Verwendung des Listenverständnisses, aber dann den Inhalt der ursprünglichen Liste ersetzen.

>>> 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

du kannst das

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

Auf Kosten der Lesbarkeit denke ich, dass diese Version etwas schneller ist, da sie nicht zwingt, die Liste noch einmal zu überprüfen.

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

Um alle doppelten Vorkommen zu entfernen und eines in der Liste zu belassen:

test = [1, 1, 2, 3]

newlist = list(set(test))

print newlist

[1, 2, 3]

Hier ist die Funktion, die ich für Project Euler verwendet habe:

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

Ich glaube, dies ist wahrscheinlich schneller als auf andere Weise, wenn Sie sich nicht um die Reihenfolge der Listen kümmern, wenn Sie sich um die endgültige Bestellung kümmern, speichern Sie die Indexe aus dem Original und greifen Sie auf diese Weise zurück.

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

Gedrungener Ansatz und Timings gegen eine Liste/Array mit 1.000.000 Elementen:

Zeiten:

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

Fazit: numpy ist 27-mal schneller (auf meinem Notebook) als beim Listenverständnis

PS, wenn Sie Ihre reguläre Python-Liste lst in ein numpy-Array konvertieren möchten:

arr = np.array(lst)

Konfiguration:

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

Prüfen:

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(' ')

Viel einfacher glaube ich.

1
marco

Erste Lösung mit Filter.
Zweite Lösung mit Listenverständnis.

#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

Entfernen Sie alle Vorkommen eines Werts aus einer Python-Liste

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()

Ergebnis: 6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11

Alternative,

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)

Ergebnis: 6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11

1
rafiqul786

Ändert dies die 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)

Vielleicht nicht der Pythonic, aber immer noch der einfachste für mich, haha

1
Ankit Sharma

Was ist falsch mit:

Motor = ['1', '2', '2'] Für i in Motor: Wenn i! = '2': Druck (i) Druck (Motor)

Anaconda verwenden 

0
code developer

Lassen

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

Die einfachste und effizienteste Lösung, wie sie bereits veröffentlicht wurde, ist

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

Eine andere Möglichkeit, die weniger Speicher benötigen, aber langsamer sein sollte, ist

>>> 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]

Timing-Ergebnisse für Listen der Länge 1000 und 100000 mit 10% übereinstimmenden Einträgen: 0,16 vs 0,25 ms und 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

['Hallo Welt']

0
SaNaMeDiO

Wenn Sie filter nicht eingebaut haben oder keinen zusätzlichen Platz benötigen, benötigen Sie eine lineare Lösung ...

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

Ich habe das nur für eine Liste gemacht. Ich bin nur ein Anfänger. Ein etwas fortgeschrittener Programmierer kann mit Sicherheit eine solche Funktion schreiben.

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