W Python remove()
usunie pierwsze wystąpienie wartości z listy.
Jak usunąć wszystkie wystąpienia wartości z listy?
Oto, co mam na myśli:
>>> remove_values_from_list([1, 2, 3, 4, 2, 2, 3], 2)
[1, 3, 4, 3]
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:
źródło
in
operator, jak iremove
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).
źródło
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:
źródło
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).Zobacz proste rozwiązanie
Zwróci to listę zawierającą wszystkie elementy
x
bez2
źródło
Wszystkie powyższe odpowiedzi (oprócz Martina Anderssona) tworzą nową listę bez żądanych elementów, zamiast usuwać elementy z oryginalnej listy.
Może to być ważne, jeśli masz inne odniesienia do listy.
Aby zmodyfikować listę na miejscu, użyj metody takiej jak ta
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.
źródło
def remove_all(x, l): return [y for y in l if y != x]
następniel = remove_all(3,l)
możesz to zrobić
źródło
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ąć:
źródło
Numpy podejście i czasy względem listy / tablicy z 1.000.000 elementów:
Czasy:
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:Ustawiać:
Czek:
źródło
źródło
Aby usunąć wszystkie zduplikowane wystąpienia i pozostawić je na liście:
Oto funkcja, której użyłem w Project Euler:
źródło
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.
źródło
O wiele łatwiejsze.
źródło
Pozwolić
Najprostszym i wydajnym rozwiązaniem, jak już wcześniej napisano, jest
Inną możliwością, która powinna zużywać mniej pamięci, ale być wolniejsza, jest
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.
źródło
Usuń wszystkie wystąpienia wartości z listy Python
Wynik:
6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11
Alternatywnie,
Wynik:
6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11
źródło
Jeśli nie masz wbudowanej
filter
lub nie chcesz używać dodatkowej przestrzeni i potrzebujesz rozwiązania liniowego ...źródło
['Witaj świecie']
źródło
Zrobiłem to tylko dla listy. Jestem tylko początkującym. Nieco bardziej zaawansowany programista z pewnością może napisać taką funkcję.
źródło
Możemy również usunąć wszystkie na miejscu za pomocą jednego
del
lub dwóchpop
:Teraz wydajność:
Jak widzimy, wersja
remove_values_from_list()
lokalna nie wymaga dodatkowej pamięci, ale jej uruchomienie zajmuje znacznie więcej czasu:źródło
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)
źródło
O prędkości!
źródło
Tylko z Python 3
źródło
Co jest źle z:
Korzystanie z anakondy
źródło