Iteracja a przestrzeń kosmiczna , użycie może być problemem. W różnych sytuacjach profilowanie może wykazywać „szybsze” i / lub „mniejsze zużycie pamięci”.
# first
>>> L = [0, 23, 234, 89, None, 0, 35, 9, ...]
>>> [x for x in L if x is not None]
[0, 23, 234, 89, 0, 35, 9, ...]
# second
>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> for i in range(L.count(None)): L.remove(None)
[0, 23, 234, 89, 0, 35, 9, ...]
Pierwsze podejście (jak również sugerowane przez @jamylak , @Raymond Hettinger i @Dipto ) tworzy jego duplikat listy w pamięci, która może być kosztowne dla dużej listy z kilku None
wpisów.
Drugie podejście przechodzi listy raz, a potem jeszcze raz za każdym razem, dopóki nie None
zostanie osiągnięta. Może to wymagać mniejszej ilości pamięci, a lista będzie się zmniejszać. Zmniejszenie rozmiaru listy może przyspieszyć wiele None
wpisów z przodu, ale najgorszym przypadku byłoby, gdyby wiele None
wpisów było z tyłu.
Techniki równoległe i lokalne są innymi podejściami, ale każda z nich ma swoje własne komplikacje w Pythonie. Znajomość danych i przypadków użycia w środowisku wykonawczym, a także profilowanie programu to miejsce, w którym można rozpocząć intensywne operacje lub duże dane.
Wybór jednego z podejść prawdopodobnie nie będzie miał znaczenia w typowych sytuacjach. Staje się bardziej preferencją zapisu. W rzeczywistości w tych rzadkich okolicznościach numpy
lub cython
mogą być wartościowymi alternatywami zamiast próbować mikromanalizować optymalizacje Pythona.
filter
wersja:filter(lambda x: x is not None, L)
- Można się pozbyćlambda
używaniapartial
ioperator.is_not
myślę, ale chyba nie warto, ponieważ lista-kompat jest o wiele czystsza.