Antworten:
Funktionsansatz:
Python 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]
Python 2.x.
>>> x = [1,2,3,2,2,2,3,4]
>>> filter(lambda a: a != 2, x)
[1, 3, 3, 4]
[y for y in x if y != 2]
__ne__
. Das Vergleichen zweier Werte ist weitaus komplexer als nur das Aufrufen __eq__
oder Aufrufen __ne__
eines dieser Werte . Hier funktioniert es möglicherweise richtig, weil Sie nur Zahlen vergleichen, aber im Allgemeinen ist das falsch und ein Fehler.
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]
in
Operator als auch die remove
Methode die gesamte Liste (bis sie eine Übereinstimmung finden), sodass Sie die Liste auf diese Weise mehrmals scannen.
Sie können die Slice-Zuweisung verwenden, wenn die ursprüngliche Liste geändert werden muss, während Sie dennoch ein effizientes Listenverständnis (oder einen Generatorausdruck) verwenden.
>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> x[:] = (value for value in x if value != 2)
>>> x
[1, 3, 4, 3]
x = [ v for v in x if x != 2 ]
Vorschlägen, bei denen eine neue Liste erstellt und x geändert wird, um darauf zu verweisen, wobei die ursprüngliche Liste unberührt bleibt.
Wiederholen Sie die Lösung des ersten Beitrags abstrakter:
>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> while 2 in x: x.remove(2)
>>> x
[1, 3, 4, 3]
x = [1] * 10000 + [2] * 1000
. Der Schleifenkörper wird 1000 Mal ausgeführt und .remove () muss bei jedem Aufruf 10000 Elemente überspringen. Das riecht für mich nach O (n * n), ist aber kein Beweis. Ich denke, der Beweis wäre anzunehmen, dass die Anzahl der 2s in der Liste proportional zu ihrer Länge ist. Dieser Proportionalitätsfaktor verschwindet dann in der Big-O-Notation. Der beste Fall von nur einer konstanten Anzahl von 2s in der Liste ist jedoch nicht O (n ^ 2), sondern nur O (2n), was O (n) ist.
Alle obigen Antworten (mit Ausnahme von 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 Sie andere Verweise auf die Liste haben.
Verwenden Sie eine solche Methode, 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 betrifft, sind die Ergebnisse auf meinem Laptop (alle auf einer 5000-Eintragsliste mit 1000 entfernten Einträgen).
Die .remove-Schleife ist also ungefähr 100x langsamer ........ Hmmm, vielleicht ist ein anderer Ansatz erforderlich. Am schnellsten habe ich das Listenverständnis verwendet, aber dann den Inhalt der ursprünglichen Liste ersetzt.
>>> def removeall_replace(x, l):
.... t = [y for y in l if y != x]
.... del l[:]
.... l.extend(t)
def remove_all(x, l): return [y for y in l if y != x]
dannl = remove_all(3,l)
du kannst das
while 2 in x:
x.remove(2)
Auf Kosten der Lesbarkeit denke ich, dass diese Version etwas schneller ist, da sie die Zeit nicht zwingt, die Liste erneut zu überprüfen, und daher genau die gleiche Arbeit erledigt, die das Entfernen sowieso tun muss:
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)
Numpy Ansatz und Timings gegen eine Liste / ein Array mit 1.000.000 Elementen:
Timings:
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 der Ansatz des Listenverständnisses
PS, wenn Sie Ihre reguläre Python-Liste lst
in ein Numpy-Array konvertieren möchten:
arr = np.array(lst)
Installieren:
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
a = [1, 2, 2, 3, 1]
to_remove = 1
a = [i for i in a if i != to_remove]
print(a)
Vielleicht nicht die pythonischste, aber immer noch die einfachste für mich, haha
So entfernen Sie alle doppelten Vorkommen und lassen eines in der Liste:
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))
Ich glaube, dies ist wahrscheinlich schneller als jede andere Möglichkeit, wenn Sie sich nicht um die Reihenfolge der Listen kümmern. Wenn Sie sich um die endgültige Reihenfolge kümmern, speichern Sie die Indizes des Originals und greifen Sie darauf zurück.
category_ids.sort()
ones_last_index = category_ids.count('1')
del category_ids[0:ones_last_index]
for i in range(a.count(' ')):
a.remove(' ')
Viel einfacher glaube ich.
Lassen
>>> x = [1, 2, 3, 4, 2, 2, 3]
Die einfachste und effizienteste Lösung, wie bereits erwähnt, ist
>>> x[:] = [v for v in x if v != 2]
>>> x
[1, 3, 4, 3]
Eine andere Möglichkeit, die weniger Speicher verbrauchen sollte, aber langsamer ist, 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 mit einer Länge von 1000 und 100000 mit 10% übereinstimmenden Einträgen: 0,16 vs 0,25 ms und 23 vs 123 ms.
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
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
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']
Ich habe das nur für eine Liste gemacht. Ich bin nur ein Anfänger. Ein etwas fortgeschrittener Programmierer kann sicherlich 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
Wir können auch alle vor Ort entfernen, indem wir entweder del
oder pop
:
import random
def remove_values_from_list(lst, target):
if type(lst) != list:
return lst
i = 0
while i < len(lst):
if lst[i] == target:
lst.pop(i) # length decreased by 1 already
else:
i += 1
return lst
remove_values_from_list(None, 2)
remove_values_from_list([], 2)
remove_values_from_list([1, 2, 3, 4, 2, 2, 3], 2)
lst = remove_values_from_list([random.randrange(0, 10) for x in range(1000000)], 2)
print(len(lst))
Nun zur Effizienz:
In [21]: %timeit -n1 -r1 x = random.randrange(0,10)
1 loop, best of 1: 43.5 us per loop
In [22]: %timeit -n1 -r1 lst = [random.randrange(0, 10) for x in range(1000000)]
g1 loop, best of 1: 660 ms per loop
In [23]: %timeit -n1 -r1 lst = remove_values_from_list([random.randrange(0, 10) for x in range(1000000)]
...: , random.randrange(0,10))
1 loop, best of 1: 11.5 s per loop
In [27]: %timeit -n1 -r1 x = random.randrange(0,10); lst = [a for a in [random.randrange(0, 10) for x in
...: range(1000000)] if x != a]
1 loop, best of 1: 710 ms per loop
Wie wir sehen, benötigt die In-Place-Version remove_values_from_list()
keinen zusätzlichen Speicher, aber die Ausführung dauert viel länger:
Niemand hat eine optimale Antwort für die zeitliche und räumliche Komplexität veröffentlicht, daher dachte ich, ich würde es versuchen. Hier ist eine Lösung, die alle Vorkommen eines bestimmten Werts entfernt, ohne ein neues Array zu erstellen, und dies zu einem effizienten Zeitpunkt. Der Nachteil ist, dass die Elemente die Reihenfolge nicht aufrechterhalten .
Zeitliche Komplexität: O (n)
Zusätzliche räumliche Komplexität: O (1)
def main():
test_case([1, 2, 3, 4, 2, 2, 3], 2) # [1, 3, 3, 4]
test_case([3, 3, 3], 3) # []
test_case([1, 1, 1], 3) # [1, 1, 1]
def test_case(test_val, remove_val):
remove_element_in_place(test_val, remove_val)
print(test_val)
def remove_element_in_place(my_list, remove_value):
length_my_list = len(my_list)
swap_idx = length_my_list - 1
for idx in range(length_my_list - 1, -1, -1):
if my_list[idx] == remove_value:
my_list[idx], my_list[swap_idx] = my_list[swap_idx], my_list[idx]
swap_idx -= 1
for pop_idx in range(length_my_list - swap_idx - 1):
my_list.pop() # O(1) operation
if __name__ == '__main__':
main()
Über die Geschwindigkeit!
import time
s_time = time.time()
print 'start'
a = range(100000000)
del a[:]
print 'finished in %0.2f' % (time.time() - s_time)
# start
# finished in 3.25
s_time = time.time()
print 'start'
a = range(100000000)
a = []
print 'finished in %0.2f' % (time.time() - s_time)
# start
# finished in 2.11
Was ist falsch mit:
Motor=['1','2','2']
For i in Motor:
If i != '2':
Print(i)
Print(motor)
Mit Anakonda