Odpowiedzi:
Podejście funkcjonalne:
Python 3.x
>>> x = [1,2,3,2,2,2,3,4]
>>> list(filter((2).__ne__, x))
[1, 3, 3, 4]
lub
>>> 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__
. Porównanie dwóch wartości jest procesem znacznie bardziej złożonym niż tylko wywołanie __eq__
lub __ne__
jedna z nich. Może tutaj działać poprawnie, ponieważ porównujesz tylko liczby, ale w ogólnym przypadku jest to niepoprawne i błąd.
Możesz użyć rozumienia listy:
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, jak i remove
metoda skanują całą listę (aż do znalezienia dopasowania), dzięki czemu skanujesz listę wiele razy w ten sposób.
Możesz użyć przypisania wycinka, jeśli oryginalna lista musi zostać zmodyfikowana, przy jednoczesnym korzystaniu ze skutecznego rozumienia listy (lub wyrażenia generatora).
>>> 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 ]
propozycjami, które tworzą nową listę i zmieniają x, aby się do niej odwoływać, pozostawiając pierwotną listę nietkniętą.
Powtarzając rozwiązanie pierwszego postu w bardziej abstrakcyjny sposób:
>>> 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
. Ciało pętli wykonuje się 1000 razy, a .remove () musi pomijać 10000 elementów przy każdym wywołaniu. Dla mnie to pachnie jak O (n * n), ale nie jest to dowodem. Myślę, że dowodem byłoby założenie, że liczba 2 na liście jest proporcjonalna do jej długości. Ten współczynnik proporcjonalności znika następnie w notacji big-O. Najlepszym jednak przypadkiem, gdy tylko stała liczba 2s na liście, nie jest O (n ^ 2), tylko O (2n), które jest O (n).
Wszystkie powyższe odpowiedzi (oprócz Martina Anderssona) tworzą nową listę bez żądanych elementów, zamiast usuwać elementy z oryginalnej listy.
>>> 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
Może to być ważne, jeśli masz inne odniesienia do listy.
Aby zmodyfikować listę na miejscu, użyj metody takiej jak ta
>>> 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
Jeśli chodzi o szybkość, wyniki na moim laptopie są (wszystkie na liście wpisów 5000 z usuniętymi 1000 wpisami)
Więc pętla .remove jest około 100 razy wolniejsza ... Hmmm, być może potrzebne jest inne podejście. Najszybsze, jakie znalazłem, korzysta ze zrozumienia listy, ale następnie zastępuję zawartość oryginalnej listy.
>>> 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]
następniel = remove_all(3,l)
możesz to zrobić
while 2 in x:
x.remove(2)
Kosztem czytelności uważam, że ta wersja jest nieco szybsza, ponieważ nie zmusza do ponownego sprawdzenia listy, dlatego wykonanie dokładnie tej samej pracy, którą trzeba usunąć:
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 podejście i czasy względem listy / tablicy z 1.000.000 elementów:
Czasy:
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
Wniosek: numpy jest 27 razy szybszy (w moim notatniku) w porównaniu do podejścia do listowania
PS, jeśli chcesz przekonwertować swoją zwykłą listę Python lst
na tablicę numpy:
arr = np.array(lst)
Ustawiać:
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
Czek:
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)
Być może nie najbardziej pytoniczny, ale wciąż najłatwiejszy dla mnie haha
Aby usunąć wszystkie zduplikowane wystąpienia i pozostawić je na liście:
test = [1, 1, 2, 3]
newlist = list(set(test))
print newlist
[1, 2, 3]
Oto funkcja, której użyłem w Project Euler:
def removeOccurrences(e):
return list(set(e))
Uważam, że jest to prawdopodobnie szybsze niż jakikolwiek inny sposób, jeśli nie przejmujesz się kolejnością list, jeśli dbasz o ostateczne zamówienie, zapisz indeksy z oryginału i skorzystaj z niego.
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(' ')
O wiele łatwiejsze.
Pozwolić
>>> x = [1, 2, 3, 4, 2, 2, 3]
Najprostszym i wydajnym rozwiązaniem, jak już wcześniej napisano, jest
>>> x[:] = [v for v in x if v != 2]
>>> x
[1, 3, 4, 3]
Inną możliwością, która powinna zużywać mniej pamięci, ale być wolniejsza, jest
>>> 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]
Wyniki pomiaru czasu dla list o długości 1000 i 100000 z 10% pasującymi wpisami: 0,16 vs 0,25 ms i 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()
Wynik: 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)
Wynik: 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
['Witaj świecie']
Zrobiłem to tylko dla listy. Jestem tylko początkującym. Nieco bardziej zaawansowany programista z pewnością może napisać taką funkcję.
for i in range(len(spam)):
spam.remove('cat')
if 'cat' not in spam:
print('All instances of ' + 'cat ' + 'have been removed')
break
Możemy również usunąć wszystkie na miejscu za pomocą jednego del
lub dwóch 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))
Teraz wydajność:
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
Jak widzimy, wersja remove_values_from_list()
lokalna nie wymaga dodatkowej pamięci, ale jej uruchomienie zajmuje znacznie więcej czasu:
Nikt nie opublikował optymalnej odpowiedzi na złożoność czasu i przestrzeni, więc pomyślałem, że dam jej szansę. Oto rozwiązanie, które usuwa wszystkie wystąpienia określonej wartości bez tworzenia nowej tablicy i przy złożonym czasie. Wadą jest to, że elementy nie utrzymują porządku .
Złożoność czasowa: O (n)
Dodatkowa złożoność przestrzeni: 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()
O prędkości!
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
Co jest źle z:
Motor=['1','2','2']
For i in Motor:
If i != '2':
Print(i)
Print(motor)
Korzystanie z anakondy