To było moje źródło, od którego zacząłem.
Moja lista
L = [0, 23, 234, 89, None, 0, 35, 9]
Kiedy uruchomię to:
L = filter(None, L)
Dostaję te wyniki
[23, 234, 89, 35, 9]
Ale nie tego potrzebuję, tak naprawdę potrzebuję:
[0, 23, 234, 89, 0, 35, 9]
Ponieważ obliczam percentyl danych, a 0 robi dużą różnicę.
Jak usunąć wartość None z listy bez usuwania wartości 0?
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.is_not
istnieje! Myślałem, że to tylkois_
, dodam to dla zabawyis_not
istnieje inot_in
nie istnieje. Myślę, żenot_in
należy to zmienić w magiczną metodę__not_contains__
... patrz pytanie, które zadałem jakiś czas temu i komentarz, który skierowałem do osoby udzielającej odpowiedzi ... i nadal nie czuję, że to zostało rozwiązane.filterfalse
lub coś w zależności od przypadku użyciax > y
nie oznacza tonot x <= y
w Pythonie, ponieważ możesz zrobić wszystko w,__lt__
a__le__
więc dlaczego miałbyśx not in y
sugerowaćnot x in y
(zwłaszcza, żenot in
ma swój własny kod bajtowy?)FWIW, Python 3 ułatwia ten problem:
W Pythonie 2 zamiast tego użyłbyś rozumienia listy:
źródło
__ne__
tego w przeciwieństwie dopartial
ine
?operator
modułu.__ne__
?x != y
wewnętrznie wywołujex.__ne__(y)
tam, gdzie ne oznacza „nie równy”. Tak,None.__ne__
jest związany metoda, która zwraca Prawda , gdy wywołana z dowolnego wartość inną niż None . Na przykładbm = None.__ne__
wywoływany zebm(10)
zwrotami NotImplemented, który jako wartość true, ibm(None)
zwraca False .Używając listy, można to zrobić w następujący sposób:
Wartość l wynosi:
źródło
W przypadku Python 2.7 (patrz odpowiedź Raymonda, odpowiednik w Python 3):
Chcąc wiedzieć, czy coś „nie jest Żaden” jest tak powszechne w pythonie (i innych językach OO), że w moim pliku Common.py (który importuję do każdego modułu za pomocą „ze wspólnego importu *”), dołączam następujące wiersze:
Następnie, aby usunąć Brak elementów z listy, po prostu wykonaj:
Uważam to za łatwiejsze do odczytania niż odpowiednie rozumienie listy (którą pokazuje Raymond jako swoją wersję Python 2).
źródło
partial(is_not, None)
to rozwiązanie. Wierzę, że będzie wolniej (choć nie jest to zbyt ważne). Ale z kilkoma importami modułów Pythona, w tym przypadku nie ma potrzeby definiowania niestandardowej funkcjiOdpowiedź @jamylak jest całkiem przyjemna, jednak jeśli nie chcesz zaimportować kilku modułów tylko do wykonania tego prostego zadania, napisz własne
lambda
w miejscu:źródło
[x for x in L if x is not None]
drugi kod był tylko dodatkiem, który wyraźnie powiedziałem, że nie polecamIteracja 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”.
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ć wieleNone
wpisów z przodu, ale najgorszym przypadku byłoby, gdyby wieleNone
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
lubcython
mogą być wartościowymi alternatywami zamiast próbować mikromanalizować optymalizacje Pythona.źródło
L.count(None)
a następnie dzwonisz.remove(None)
wiele razy, co powoduje, żeO(N^2)
sytuacja, którą próbujesz rozwiązać, nie powinna być rozwiązana w ten sposób, dane powinny zostać zrestrukturyzowane zamiast tego do bazy danych lub pliku, jeśli zajmuje dużo pamięci.O(n^2)
jest tylko wtedy, gdy cała lista jestNone
.numpy
byłby w stanie poradzić sobie z tego typu operacjami w bardziej zoptymalizowany sposóbnumpy
w ostatnich latach, ale jest to osobna umiejętność. JeśliL
jest tworzony jakonumpy.array
zamiast Pythonalist
, toL = L[L != numpy.array(None)]
(stackoverflow.com/a/25255015/3003133) jest prawdopodobnie lepszy niż którykolwiek z nich, ale nie znam szczegółów implementacji przetwarzania względem pamięci poniżej. Co najmniej tworzy tablicę duplikatów wartości logicznych dla maski. W ten sposób składnia porównania wewnątrz operatora dostępu (indeksu) jest dla mnie nowa. Ta dyskusja zwróciła również moją uwagędtype=object
.źródło
Jeśli jest to tylko lista list, możesz zmodyfikować odpowiedź sir @ Raymonda
L = [ [None], [123], [None], [151] ] no_none_val = list(filter(None.__ne__, [x[0] for x in L] ) )
dla Pythona 2no_none_val = [x[0] for x in L if x[0] is not None] """ Both returns [123, 151]"""
<< list_indice [0] dla zmiennej na liście, jeśli zmienna nie jest żadna >>
źródło
Powiedzmy, że lista jest jak poniżej
Zwróci tylko te przedmioty, których
bool(item) is True
Jest to równoważne z
Aby po prostu filtrować Brak:
Równoważny:
Aby uzyskać wszystkie elementy, które oceniają na False
źródło