Ieruję listę krotek w Pythonie i próbuję je usunąć, jeśli spełniają określone kryteria.
for tup in somelist:
if determine(tup):
code_to_remove_tup
Czego powinienem użyć zamiast code_to_remove_tup
? Nie mogę wymyślić, jak usunąć przedmiot w ten sposób.
Odpowiedzi:
Możesz użyć zrozumienia listy, aby utworzyć nową listę zawierającą tylko elementy, których nie chcesz usuwać:
Lub przypisując do plasterka
somelist[:]
, możesz zmutować istniejącą listę, aby zawierała tylko te elementy, które chcesz:Takie podejście może być przydatne, jeśli istnieją inne odniesienia do
somelist
tej potrzeby, aby odzwierciedlić zmiany.Zamiast zrozumienia możesz także użyć
itertools
. W Python 2:Lub w Python 3:
Dla jasności i dla tych, którzy używają
[:]
notacji hackish lub fuzzy, oto bardziej wyraźna alternatywa. Teoretycznie powinien on działać tak samo w odniesieniu do przestrzeni i czasu, jak powyższe linijki.Działa również w innych językach, które mogą nie mieć możliwości zamiany elementów list Pythona, z minimalnymi modyfikacjami. Na przykład, nie wszystkie języki przesyłają puste listy do a,
False
tak jak Python. Możesz zastąpićwhile somelist:
coś bardziej wyraźnego, na przykładwhile len(somelist) > 0:
.źródło
somelist[:] = (x for x in somelist if determine(x))
tego, aby utworzyć generator, który może nie tworzyć niepotrzebnych kopii.list_ass_slice()
funkcja, która implementujesomelist[:]=
wywołaniaPySequence_Fast()
wewnętrznie. Ta funkcja zawsze zwraca listę, tzn. Rozwiązanie @Alex Martelli, które już korzysta z listy zamiast z generatora, jest najprawdopodobniej bardziej wydajnesomelist
nie zostałaby zmutowana w obu metodach?Odpowiedzi sugerujące zrozumienie listy są PRAWIE NIEPRAWIDŁOWE - poza tym, że budują zupełnie nową listę, a następnie nadają jej tę samą nazwę, co stara lista, ponieważ NIE modyfikują starej listy w miejscu. Różni się to od tego, co robisz przez selektywne usuwanie, jak sugeruje @ Lennart - jest szybsze, ale jeśli twoja lista jest dostępna za pomocą wielu referencji, fakt, że po prostu resetujesz jedno z referencji i NIE zmieniasz obiektu listy samo w sobie może prowadzić do subtelnych, katastrofalnych błędów.
Na szczęście niezwykle łatwo jest uzyskać zarówno szybkość analiz listowych, jak i wymaganą semantykę modyfikacji w miejscu - wystarczy kod:
Zwróć uwagę na subtelną różnicę w stosunku do innych odpowiedzi: ta NIE przypisuje się do nagiej nazwy - przypisuje ją do wycinka listy, który akurat jest całą listą, zastępując w ten sposób zawartość listy w tym samym obiekcie listy Python , zamiast tylko ponownego umieszczania jednego odwołania (od poprzedniego obiektu listy do nowego obiektu listy), podobnie jak inne odpowiedzi.
źródło
a
treścią dictb
, użyja.clear(); a.update(b)
.x = ['foo','bar','baz']; y = x; x = [item for item in x if determine(item)];
przypisujex
się to wynikowi zrozumienia listy, aley
nadal odnosi się do oryginalnej listy['foo','bar','baz']
. Jeśli się spodziewałeśx
iy
odwołujesz się do tej samej listy, być może wprowadziłeś błędy. Temu zapobiec poprzez przypisanie do plasterka całej listy, jak pokazuje Alex i pokażę tutaj:x = ["foo","bar","baz"]; y = x; x[:] = [item for item in x if determine(item)];
. Lista jest modyfikowana na miejscu. upewniając się, że wszystkie odniesienia do listy (zarówno tutaj, jakx
iy
tutaj) odnoszą się do nowej listy.filter
funkcji również tworzy nową listę, nie modyfikuje elementów w miejscu ... tylkoolist[:] = [i for i in olist if not dislike(i)]
Musisz najpierw wykonać kopię listy i powtórzyć ją, w przeciwnym razie iteracja zakończy się niepowodzeniem, co może być nieoczekiwanym rezultatem.
Na przykład (zależy od typu listy):
Przykład:
źródło
list(somelist)
przekształci iterowalny w listę.somelist[:]
tworzy kopię obiektu obsługującego krojenie. Więc niekoniecznie robią to samo. W tym przypadku chcę zrobić kopięsomelist
obiektu, więc używam[:]
remove()
musi przejrzeć CAŁĄ listę dla każdej iteracji, więc zajmie to wieczność.Musisz cofnąć się w przeciwnym razie przypomina to ścinanie gałęzi, na której siedzisz :-)
Użytkownicy Python 2: zamień
range
na,xrange
aby uniknąć tworzenia listy zakodowanej na stałeźródło
reversed()
wbudowanegoenumerate
zwraca iterator ireversed
oczekuje sekwencji. Myślę, że możesz to zrobić,reversed(list(enumerate(somelist)))
jeśli nie masz nic przeciwko tworzeniu dodatkowej listy w pamięci.m
czasem wolniejsze.Oficjalny samouczek języka Python 2 4.2. „dla wyciągów”
https://docs.python.org/2/tutorial/controlflow.html#for-statements
Ta część dokumentacji wyjaśnia, że:
[:]
Dokumentacja Python 2 7.3. „Oświadczenie za”
https://docs.python.org/2/reference/compound_stmts.html#for
Ta część dokumentów mówi jeszcze raz, że musisz zrobić kopię, i podaje rzeczywisty przykład usunięcia:
Jednak nie zgadzam się z tą implementacją, ponieważ
.remove()
musi iterować całą listę aby znaleźć wartość.Najlepsze obejścia
Zarówno:
rozpocznij nową tablicę od zera i
.append()
na końcu: https://stackoverflow.com/a/1207460/895245Ten czas jest efektywny, ale zajmuje mniej miejsca, ponieważ utrzymuje kopię tablicy podczas iteracji.
użyj
del
z indeksem: https://stackoverflow.com/a/1207485/895245Jest to bardziej wydajne pod względem miejsca, ponieważ dozuje kopię tablicy, ale jest mniej wydajne czasowo, ponieważ listy CPython są implementowane za pomocą tablic dynamicznych .
Oznacza to, że usunięcie przedmiotu wymaga przesunięcia wszystkich kolejnych elementów o jeden, czyli O (N).
Ogólnie rzecz biorąc, po prostu chcesz iść szybciej
.append()
domyślnie wybrać opcję, chyba że problemem jest pamięć.Czy Python mógłby to zrobić lepiej?
Wygląda na to, że ten konkretny interfejs API języka Python można ulepszyć. Porównaj to na przykład z:
std::vector::erase
który zwraca poprawny interator do elementu po usuniętymoba z nich wyraźnie pokazują, że nie można modyfikować iterowanej listy, z wyjątkiem samego iteratora, i zapewniają efektywne sposoby wykonania tego bez kopiowania listy.
Być może podstawowym uzasadnieniem jest to, że zakłada się, że listy Pythona są dynamicznie wspierane przez tablicę, a zatem wszelkie typy usuwania będą i tak nieefektywne czasowo, podczas gdy Java ma lepszą hierarchię interfejsu zarówno z implementacjami, jak
ArrayList
iLinkedList
ListIterator
.Wydaje się, że w stdlib Pythona nie ma jawnie połączonej listy typów: Python Linked List
źródło
Najlepszym podejściem do takiego przykładu byłoby zrozumienie listy
W przypadkach, w których robisz coś bardziej złożonego niż wywoływanie
determine
funkcji, wolę zbudować nową listę i po prostu dołączyć do niej podczas pracy. Na przykładSkopiowanie listy za pomocą
remove
może sprawić, że Twój kod będzie wyglądał na bardziej przejrzysty, jak opisano w jednej z odpowiedzi poniżej. Zdecydowanie nie powinieneś tego robić w przypadku bardzo dużych list, ponieważ wymaga to najpierw skopiowania całej listy, a także wykonaniaO(n)
remove
operacji dla każdego usuwanego elementu, co czyni z niegoO(n^2)
algorytm.źródło
Dla tych, którzy lubią programowanie funkcjonalne:
lub
źródło
filter
i bardziej Pythonic. 2. Jeśli potrzebujeszlambda
użyćmap
lubfilter
, lista komp lub genexpr jest zawsze lepszą opcją;map
ifilter
może być nieco szybszy, gdy funkcja transformacji / predykatu jest wbudowanym Pythonem zaimplementowanym w C, a iterowalność nie jest trywialnie mała, ale zawsze są one wolniejsze, gdy potrzebujesz listylambda
, której listcomp / genexpr mógłby uniknąć.Musiałem to zrobić z ogromną listą, a powielenie listy wydawało się drogie, zwłaszcza że w moim przypadku liczba usunięć byłaby niewielka w porównaniu z pozostałymi elementami. Przyjąłem to podejście na niskim poziomie.
To, czego nie wiem, to skuteczność kilku operacji usuwania w porównaniu z kopiowaniem dużej listy. Proszę o komentarz, jeśli masz jakiś wgląd.
źródło
list
należy przede wszystkim starannie rozważyć wybór jako struktury danych, ponieważ usunięcie ze środka listy zajmuje liniowy czas na długości listy. Jeśli tak naprawdę nie potrzebujesz losowego dostępu do k-tego sekwencyjnego elementu, może zastanów sięOrderedDict
?newlist = []
, a potemnewlist.append(array[i])
tuż przeddel array[i]
?list()
jest to lista połączona, dostęp losowy jest drogi, jeślilist()
jest tablicą, usuwanie jest kosztowne, ponieważ wymaga przesunięcia wszystkich następujących elementów do przodu. Przyzwoity iterator może pomóc w implementacji listy połączonej. Może to jednak być efektywne pod względem przestrzeni.Rozsądne może być również utworzenie nowej listy, jeśli bieżący element listy spełnia wymagane kryteria.
więc:
i aby uniknąć konieczności ponownego kodowania całego projektu przy użyciu nazwy nowych list:
Uwaga, z dokumentacji Python:
źródło
Ta odpowiedź została pierwotnie napisana w odpowiedzi na pytanie, które zostało oznaczone jako duplikat: Usuwanie współrzędnych z listy w pythonie
W twoim kodzie są dwa problemy:
1) Korzystając z funkcji remove (), próbujesz usunąć liczby całkowite, ale musisz usunąć krotkę.
2) Pętla for spowoduje pominięcie pozycji na liście.
Zobaczmy, co się stanie, gdy wykonamy Twój kod:
Pierwszy problem polega na tym, że przekazujesz zarówno „a”, jak i „b” do remove (), ale remove () akceptuje tylko jeden argument. Jak więc możemy usunąć remove (), aby działał poprawnie z twoją listą? Musimy dowiedzieć się, jaki jest każdy element twojej listy. W tym przypadku każdy jest krotką. Aby to zobaczyć, uzyskajmy dostęp do jednego elementu listy (indeksowanie zaczyna się od 0):
Aha! Każdy element L1 jest w rzeczywistości krotką. Właśnie to musimy przekazać, aby usunąć (). Krotki w pythonie są bardzo proste, są po prostu tworzone przez umieszczanie wartości w nawiasach. „a, b” nie jest krotką, ale „(a, b)” jest krotką. Zmodyfikujemy więc Twój kod i uruchomimy go ponownie:
Ten kod działa bezbłędnie, ale spójrzmy na listę, którą wypisuje:
Dlaczego (1, -2) jest nadal na twojej liście? Okazuje się, że modyfikowanie listy podczas iteracji w pętli jest bardzo złym pomysłem bez specjalnej uwagi. Powodem, dla którego (1, -2) pozostaje na liście, jest to, że lokalizacje każdego elementu na liście zmieniały się między iteracjami pętli for. Zobaczmy, co się stanie, jeśli podamy powyższy kod dłuższą listę:
Jak można wywnioskować z tego wyniku, za każdym razem, gdy instrukcja warunkowa ma wartość true, a element listy jest usuwany, następna iteracja pętli pomija ocenę następnego elementu na liście, ponieważ jego wartości są teraz zlokalizowane w różnych indeksach.
Najbardziej intuicyjnym rozwiązaniem jest skopiowanie listy, a następnie iterowanie oryginalnej listy i modyfikowanie tylko kopii. Możesz spróbować zrobić to w ten sposób:
Jednak dane wyjściowe będą identyczne jak wcześniej:
Wynika to z faktu, że kiedy stworzyliśmy L2, Python tak naprawdę nie utworzył nowego obiektu. Zamiast tego odwoływał się jedynie do L2 do tego samego obiektu co L1. Możemy to zweryfikować za pomocą „is”, który różni się od zwykłego „equals” (==).
Możemy wykonać prawdziwą kopię za pomocą copy.copy (). Wtedy wszystko działa zgodnie z oczekiwaniami:
Wreszcie istnieje jedno czystsze rozwiązanie niż konieczność zrobienia całkowicie nowej kopii L1. Funkcja reverse ():
Niestety nie potrafię odpowiednio opisać, jak działa reverse (). Zwraca obiekt „listreverseiterator”, gdy lista jest do niego przekazywana. Ze względów praktycznych można go traktować jako tworzenie odwróconej kopii jego argumentu. To rozwiązanie polecam.
źródło
Jeśli chcesz zrobić cokolwiek innego podczas iteracji, może być miło uzyskać zarówno indeks (co gwarantuje, że możesz się do niego odwoływać, na przykład, jeśli masz listę nagrań), jak i faktyczną zawartość elementu listy.
enumerate
daje dostęp do elementu i indeksu jednocześnie.reversed
polega na tym, że wskaźniki, które zamierzasz później usunąć, nie zmieniają się dla Ciebie.źródło
Możesz użyć
filter()
dostępny jako wbudowany.Po więcej szczegółów sprawdź tutaj
źródło
Większość odpowiedzi tutaj chce, abyś utworzył kopię listy. Miałem przypadek użycia, w którym lista była dość długa (110 000 pozycji) i rozsądniej było zamiast tego zmniejszać listę.
Przede wszystkim musisz zamienić pętlę foreach na pętlę while ,
Wartość
i
nie zmienia się w bloku if, ponieważ po usunięciu starego elementu będziesz chciał uzyskać wartość nowego elementu Z TEGO SAMEGO INDEKSU.źródło
Możesz spróbować for-looping w odwrotnej kolejności, więc dla some_list możesz zrobić coś takiego:
W ten sposób indeks jest wyrównany i nie cierpi z powodu aktualizacji listy (niezależnie od tego, czy pop element jest pobierany, czy nie).
źródło
reversed(list(enumerate(some_list)))
byłaby prostsza niż samodzielne obliczanie indeksów.Jedno możliwe rozwiązanie, przydatne, jeśli chcesz nie tylko usunąć niektóre rzeczy, ale także zrobić coś ze wszystkimi elementami w jednej pętli:
źródło
bad
coś usunąć , zrobić coś z tym, a także zrobić coś zgood
rzeczami w jednej pętli?alist[:]
) A ponieważ możesz robić coś fantazyjnego, w rzeczywistości ma ona zastosowanie. Dobra wersja jest dobra. Weź moją opinię.Musiałem zrobić coś podobnego, aw moim przypadku problemem była pamięć - musiałem scalić wiele obiektów zestawu danych na liście, po zrobieniu z nimi pewnych rzeczy jako nowego obiektu i musiałem pozbyć się każdego wpisu, z którym się łączyłem unikaj powielania ich wszystkich i niszczenia pamięci. W moim przypadku dobrze działały obiekty w słowniku zamiast listy:
``
``
źródło
TLDR:
Napisałem bibliotekę, która pozwala ci to zrobić:
Najlepiej jest użyć innej metody, jeśli to możliwe, która nie wymaga modyfikowania iteracji podczas iteracji, ale w przypadku niektórych algorytmów może nie być to takie proste. Jeśli więc masz pewność, że naprawdę chcesz wzorca kodu opisanego w pierwotnym pytaniu, jest to możliwe.
Powinien działać na wszystkich zmiennych sekwencjach, a nie tylko na listach.
Pełna odpowiedź:
Edycja: Ostatni przykładowy kod w tej odpowiedzi podaje przypadek użycia, dla którego czasami warto zmodyfikować listę zamiast używać jej interpretacji. Pierwsza część odpowiedzi służy jako samouczek na temat sposobu modyfikowania tablicy w miejscu.
Rozwiązanie wynika z tego odpowiedzi (na powiązane pytanie) od nadawcy. To wyjaśnia, w jaki sposób indeks tablicy jest aktualizowany podczas iteracji po zmodyfikowanej liście. Poniższe rozwiązanie ma na celu prawidłowe śledzenie indeksu tablicy, nawet jeśli lista zostanie zmodyfikowana.
Pobrać
fluidIter.py
z tutajhttps://github.com/alanbacon/FluidIterator
, to tylko jeden plik, więc nie ma potrzeby instalowania git. Nie ma instalatora, więc musisz sam upewnić się, że plik znajduje się w ścieżce Pythona. Kod został napisany dla Pythona 3 i nie jest testowany w Pythonie 2.Spowoduje to wygenerowanie następującego wyniku:
Powyżej zastosowaliśmy
pop
metodę na obiekcie listy płynów. Inne typowe metody iterowalny realizowane są także takie jakdel fluidL[i]
,.remove
,.insert
,.append
,.extend
. Lista może być również modyfikowana za pomocą plasterków (sort
ireverse
metody nie są zaimplementowane).Jedynym warunkiem jest to, że musisz modyfikować listę tylko w miejscu, jeśli w dowolnym momencie
fluidL
lub zostałeśl
ponownie przypisany do innego obiektu listy, kod nie działałby. OryginalnyfluidL
obiekt nadal byłby używany przez pętlę for, ale stałby się poza zasięgiem, abyśmy mogli go modyfikować.to znaczy
Jeśli chcemy uzyskać dostęp do bieżącej wartości indeksu listy, nie możemy użyć wyliczenia, ponieważ liczy się tylko ile razy uruchomiona została pętla for. Zamiast tego użyjemy bezpośrednio obiektu iteratora.
Spowoduje to wyświetlenie następujących danych:
FluidIterable
Klasa tylko zapewnia otoki na pierwotnej liście obiektu. Dostęp do oryginalnego obiektu można uzyskać jako właściwość obiektu płynnego w następujący sposób:Więcej przykładów / testów można znaleźć w
if __name__ is "__main__":
sekcji na dolefluidIter.py
. Warto na nie spojrzeć, ponieważ wyjaśniają, co dzieje się w różnych sytuacjach. Na przykład: Zastępowanie dużych sekcji listy za pomocą wycinka. Lub używając (i modyfikując) tę samą iterowalną w zagnieżdżonej pętli.Tak jak powiedziałem na początek: jest to skomplikowane rozwiązanie, które pogorszy czytelność twojego kodu i utrudni debugowanie. Dlatego też inne rozwiązania, takie jak listowe lista wymienionych w Davida Raznick za odpowiedzi należy rozważyć w pierwszej kolejności. Biorąc to pod uwagę, znalazłem czasy, w których ta klasa była dla mnie przydatna i łatwiejsza w użyciu niż śledzenie wskaźników elementów, które należy usunąć.
Edycja: Jak wspomniano w komentarzach, ta odpowiedź tak naprawdę nie stanowi problemu, dla którego to podejście zapewnia rozwiązanie. Spróbuję rozwiązać ten problem tutaj:
Wyjaśnienia list umożliwiają generowanie nowej listy, ale te podejścia mają tendencję do patrzenia na każdy element osobno, a nie na bieżący stan listy jako całości.
to znaczy
Ale co jeśli wynik
testFunc
zależy od elementów, które zostałynewList
już dodane ? Lub elementy nadal woldList
tym, mogą zostać dodane później? Nadal może istnieć sposób korzystania ze zrozumienia listy, ale zacznie tracić swoją elegancję i dla mnie łatwiej jest zmodyfikować listę na miejscu.Poniższy kod jest przykładem algorytmu, który cierpi z powodu powyższego problemu. Algorytm zmniejszy listę, aby żaden element nie był wielokrotnością żadnego innego elementu.
Dane wyjściowe i końcowa lista zredukowana są pokazane poniżej
źródło
some_list[:] = [x for x in some_list if not some_condition(x)]
czego nie osiąga? Bez odpowiedzi na to pytanie, dlaczego ktokolwiek miałby wierzyć, że pobieranie i korzystanie z 600-liniowej biblioteki wraz z literówkami i komentarzem jest lepszym rozwiązaniem ich problemu niż jednoliniowa? -1.some_list[:] = [x for x in some_list if not some_condition(y)]
gdziey
jest inny element listyx
. Nie byłoby też możliwe pisaniesome_list[:] = [x for x in some_list if not some_condition(intermediateStateOf_some_list)]
.Najskuteczniejszą metodą jest lista zrozumienie, wiele osób pokazać swoją sprawę, oczywiście, jest to również dobry sposób, aby uzyskać
iterator
throughfilter
.Jest przykład (zdobądź szanse na krotkę):
Uwaga: Nie można również obsługiwać iteratorów. Iteratory są czasem lepsze niż sekwencje.
źródło
pętla będzie iterować przez indeks ..
uważają, że masz listę,
używasz zmiennej listy o nazwie
lis
. a ty używasz tego samego do usunięcia ...twoja zmienna
podczas piątej iteracji
twój numer 35 nie był liczbą pierwszą, więc usunąłeś go z listy.
a następnie następna wartość (65) przechodzi do poprzedniego indeksu.
więc wskaźnik wykonanej 4. iteracji przesunięty na 5.
dlatego twoja pętla nie obejmuje 65, ponieważ została przeniesiona do poprzedniego indeksu.
więc nie powinieneś odwoływać się do listy do innej zmiennej, która wciąż odwołuje się do oryginału zamiast do kopiowania.
więc skopiuj listę używając
list[::]
teraz da ci
Problem polega na tym, że podczas iteracji usunięto wartość z listy, a następnie indeks listy się zwinął.
więc zamiast tego możesz spróbować zrozumieć.
który obsługuje wszystkie iterowalne opcje, takie jak: lista, krotka, dict, ciąg itp
źródło
Jeśli chcesz usunąć elementy z listy podczas iteracji, użyj pętli while, aby móc zmieniać bieżący indeks i indeks końcowy po każdym usunięciu.
Przykład:
źródło
Pozostałe odpowiedzi są poprawne, ponieważ zazwyczaj jest to zły pomysł, aby usunąć z listy, którą iterujesz. Odwrotne iterowanie pozwala uniknąć pułapek, ale znacznie trudniej jest podążać za kodem, który to robi, więc zwykle lepiej jest używać rozumienia listy lub
filter
.Jest jednak jeden przypadek, w którym można bezpiecznie usunąć elementy z sekwencji, którą iterujesz: jeśli usuwasz tylko jeden element podczas iteracji. Można to zapewnić za pomocą a
return
lub abreak
. Na przykład:Jest to często łatwiejsze do zrozumienia niż zrozumienie listy, gdy wykonujesz pewne operacje z efektami ubocznymi na pierwszym elemencie na liście, który spełnia pewien warunek, a następnie usuwasz go z listy natychmiast po.
źródło
Mogę wymyślić trzy podejścia do rozwiązania twojego problemu. Jako przykład utworzę losową listę krotek
somelist = [(1,2,3), (4,5,6), (3,6,6), (7,8,9), (15,0,0), (10,11,12)]
. Warunek, który wybrałem, jestsum of elements of a tuple = 15
. Na końcowej liście będziemy mieć tylko te krotki, których suma nie jest równa 15.To, co wybrałem, to losowo wybrany przykład. Krępuj się zmienić na listę krotek i kondycję , które wybrałem.
Metoda 1.> Użyj zaproponowanego frameworka (gdzie wypełnia się kod wewnątrz pętli for). Używam małego kodu,
del
aby usunąć krotkę spełniającą ten warunek. Jednak ta metoda pominie krotkę (która spełnia wspomniany warunek), jeśli dwa kolejno umieszczone krotki spełniają dany warunek.Metoda 2.> Skonstruuj nową listę zawierającą elementy (krotki), w których dany warunek nie jest spełniony (jest to to samo, co usunięcie elementów listy, w których dany warunek jest spełniony). Oto kod do tego:
Metoda 3.> Znajdź indeksy, w których spełniony jest dany warunek, a następnie użyj elementów usuwających (krotek) odpowiadających tym indeksom. Poniżej znajduje się kod do tego.
Metoda 1 i metoda 2 są szybsze niż metoda 3 . Metoda 2 i metoda 3 są bardziej wydajne niż metoda 1. I wolą Method2 . W powyższym przykładzie
time(method1) : time(method2) : time(method3) = 1 : 1 : 1.7
źródło
Do wszystkiego, co może być naprawdę duże, używam następujących.
To powinno być znacznie szybsze niż cokolwiek innego.
źródło
W niektórych sytuacjach, gdy robisz coś więcej niż tylko filtrowanie listy pojedynczo, chcesz, aby iteracja zmieniła się podczas iteracji.
Oto przykład, w którym wcześniejsze skopiowanie listy jest nieprawidłowe, odwrotna iteracja jest niemożliwa, a zrozumienie listy również nie jest możliwe.
źródło
Jeśli później użyjesz nowej listy, możesz po prostu ustawić element na Brak, a następnie ocenić go w późniejszej pętli, tak jak to
W ten sposób nie musisz kopiować listy i łatwiej to zrozumieć.
źródło
wymyśl listę liczb, a chcesz usunąć wszystkie nie, które są podzielne przez 3,
przy użyciu
list comprehension
spowoduje to zmianę nowej listy i utworzenie nowej przestrzeni pamięciużycie
lambda filter
funkcji spowoduje utworzenie nowej listy wynikowej i zajmie miejsce w pamięcibez zajmowania miejsca w pamięci dla nowej listy i modyfikowania istniejącej listy
źródło