Jak sprawdzić, czy lista jest pusta?


3234

Na przykład, jeśli przekazano następujące:

a = []

Jak sprawdzić, czy ajest pusty?

Odpowiedzi:


5488
if not a:
  print("List is empty")

Używanie ukrytej wartości logicznej pustej listjest dość pytoniczne.


1128
Gra adwokata diabła. Nie rozumiem, dlaczego ten idiom jest uważany za pytoniczny. „Jawne jest lepsze niż niejawne”, prawda? Ta kontrola nie wydaje się bardzo wyraźna na temat tego, co jest sprawdzane.
James McMahon

222
@JamesMcMahon - to kompromis między jawnością a elastycznością typu. ogólnie „bycie jawnym” oznacza nie robienie „magicznych” rzeczy. z drugiej strony „pisanie kaczką” oznacza pracę z bardziej ogólnymi interfejsami, zamiast jawnego sprawdzania typów. więc coś takiego if a == []wymusza określony typ ( () == []jest False). tutaj ogólny konsensus wydaje się być taki, że wygrywa pisanie kaczek (w efekcie mówiąc, że __nonzero__jest to interfejs do testowania pustki docs.python.org/reference/datamodel.html#object.__nonzero__ )
andrew cooke

38
Ta metoda nie działa na tablicach numpy. Myślę, że jeśli len (a) == 0 jest preferowany zarówno pod względem „pisania kaczego”, jak i niejawności.
Mr.WorshipMe

10
Kanonicznym sposobem sprawdzenia, czy tablica w C jest pusta, jest usunięcie dereferencji z pierwszego elementu i sprawdzenie, czy jest ona pusta, przy założeniu, że tablica jest zakończona zerem. W przeciwnym razie porównanie jego długości do zera jest całkowicie nieefektywne, jeśli tablica ma znaczny rozmiar. Zazwyczaj nie przydziela się pamięci dla pustej tablicy (wskaźnik pozostaje pusty), więc nie ma sensu próbować uzyskać jej długości. Nie twierdzę, że len (a) == 0 nie jest dobrym sposobem na zrobienie tego, po prostu nie krzyczy do mnie „C”, kiedy go widzę.
sleblanc

6
@BrennenSprimont, Jeśli nie jest zakończony zerem, oznacza to, że znasz już długość, czy jest ona przechowywana w osobnej zmiennej, czy twoja tablica jest zapakowana w jakiś kontener, który śledzi długość. C ++, Java, C # mają takie kontenery i skutecznie implementują metodę „length”. C nie ma czegoś takiego , musisz rzucić własnym. Statycznie przydzielone tablice C są tylko wskaźnikami do obszaru pamięci, który gwarantuje wystarczającą ilość miejsca do przechowywania żądanej ilości danych. Nie ma nic wbudowanego w C, co dałoby ci znać, ile już wypełniłeś to miejsce.
sleblanc

1158

Pythoniczny sposób na to jest z przewodnika po stylu PEP 8 (gdzie „ Tak ” oznacza „zalecane”, a „ Nie ” oznacza „niezalecane”):

W przypadku sekwencji (ciągów, list, krotek) użyj faktu, że puste sekwencje są fałszywe.

Yes: if not seq:
     if seq:

No:  if len(seq):
     if not len(seq):

49
Drugi sposób wydaje się lepszy, jeśli chcesz zasygnalizować, że seqma to być obiekt listy.
BallpointBen

5
@BallpointBen, który, jak twierdzą zwolennicy Pythonizmu, powinien być domyślnie imitowany tak, jak nazywa się zmienną, w jak największym stopniu
axolotl

9
@BallpointBen spróbuj użyć podpowiedzi typu Python do zasygnalizowania, jaka powinna być zmienna. Został wprowadzony w wersji 3.5.
Boris

8
numpy złamał ten idiom ... seq = numpy.array ([1,2,3]), a następnie jeśli nie seq podnosi wyjątek "ValueError: Wartość prawdy tablicy z więcej niż jednym elementem jest niejednoznaczna. Użyj a.any () lub a.all () ”
Mr.WorshipMe

2
@jeronimo: Uważam, że jest to ostrzeżenie specyficzne dla lxml.
Harley Holcombe

767

Wolę to wyraźnie:

if len(li) == 0:
    print('the list is empty')

W ten sposób jest w 100% jasne, że lijest to sekwencja (lista) i chcemy przetestować jej rozmiar. Mój problem if not li: ...polega na tym, że daje fałszywe wrażenie, że lijest zmienną logiczną.


91
Sprawdzanie, czy długość listy jest równa zeru, zamiast tylko sprawdzania, czy lista jest fałszywa, jest brzydka i pozbawiona mitów. Każdy, kto zna Python, w ogóle nie pomyśli, że lito bool, i nie będzie go to obchodzić. Jeśli to ważne, powinieneś dodać komentarz, a nie więcej kodu.
Carl Smith,

21
Wydaje się to niepotrzebnie precyzyjnym testem, który często jest wolniejszy i zawsze jest mniej czytelny IMHO. Zamiast sprawdzać rozmiar czegoś pustego, dlaczego po prostu nie sprawdzić, czy jest pusty?
John B,

34
W każdym razie powodem, dla którego jest to złe (i że naruszanie idiomów w języku z silnymi idiomami, takimi jak Python, jest ogólnie złe) jest to, że sygnalizuje czytelnikowi, że z jakiegoś powodu konkretnie sprawdzasz długość (np. Dlatego, że chcesz Nonelub 0zamiast stawiać wyjątek). Tak więc, gdy robisz to bez powodu, to jest mylące, a to oznacza również, że gdy Twój kod ma potrzeby wprowadzania rozróżnienia, rozróżnienie jest niewidoczny, ponieważ masz „Płakał wilk” całej reszty źródła.
abarnert

18
Myślę, że to po prostu niepotrzebnie wydłuża kod. W przeciwnym razie, dlaczego nie być jeszcze bardziej „wyraźnym” if bool(len(li) == 0) is True:?
sierpień

11
@Jabba będzie to O (1) w wielu przypadkach (te, w których pracujesz z wbudowanymi typami danych), ale po prostu nie możesz na tym polegać. Być może pracujesz z niestandardowym typem danych, który nie ma tej właściwości. Możesz również zdecydować o dodaniu tego niestandardowego typu danych później, po napisaniu tego kodu.
ralokt

324

To jest pierwsze trafienie w Google dla „pustej tablicy Pythona” i podobnych zapytań, a inni wydają się uogólniać pytanie poza tylko listami, więc pomyślałem, że dodam zastrzeżenie dla innego rodzaju sekwencji, niż wiele osób może użyć.

Inne metody nie działają dla tablic NumPy

Trzeba uważać na tablice NumPy, ponieważ inne metody, które działają dobrze dla lists lub innych standardowych kontenerów, zawodzą w przypadku tablic NumPy. Wyjaśniam dlaczego, ale w skrócie, preferowaną metodą jest użycie size.

„Pythonowy” sposób nie działa: Część 1

Metoda „pytoniczna” kończy się niepowodzeniem w przypadku tablic NumPy, ponieważ NumPy próbuje rzutować tablicę na tablicę bools i if xpróbuje ocenić wszystkie te wartości boolnaraz dla pewnego rodzaju zagregowanej wartości prawdy. Ale to nie ma sensu, więc otrzymujesz ValueError:

>>> x = numpy.array([0,1])
>>> if x: print("x")
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Sposób „pythonowy” nie działa: część 2

Ale przynajmniej powyższy przypadek mówi ci, że się nie udało. Jeśli zdarzy ci się, że masz tablicę NumPy z dokładnie jednym elementem, ifinstrukcja będzie „działać” w tym sensie, że nie otrzymasz błędu. Jeśli jednak tym elementem będzie 0(lub 0.0, lub False...), ifinstrukcja niepoprawnie spowoduje False:

>>> x = numpy.array([0,])
>>> if x: print("x")
... else: print("No x")
No x

Ale wyraźnie xistnieje i nie jest pusty! Ten wynik nie jest tym, czego chciałeś.

Korzystanie lenmoże dać nieoczekiwane rezultaty

Na przykład,

len( numpy.zeros((1,0)) )

zwraca 1, mimo że tablica zawiera zero elementów.

Sposób numpythonic

Jak wyjaśniono w SciPy FAQ , poprawną metodą we wszystkich przypadkach, w których wiesz, że masz tablicę NumPy, jest użycie if x.size:

>>> x = numpy.array([0,1])
>>> if x.size: print("x")
x

>>> x = numpy.array([0,])
>>> if x.size: print("x")
... else: print("No x")
x

>>> x = numpy.zeros((1,0))
>>> if x.size: print("x")
... else: print("No x")
No x

Jeśli nie masz pewności, czy może to być listtablica NumPy, czy coś innego, możesz połączyć to podejście z odpowiedzią podaną przez @dubiousjim, aby upewnić się, że dla każdego typu zastosowano odpowiedni test. Niezbyt „pythoniczny”, ale okazuje się, że NumPy celowo złamał pythonicity przynajmniej w tym sensie.

Jeśli trzeba zrobić więcej niż po prostu sprawdzić, czy wkład jest pusty, a używasz innego NumPy takich jak operacje indeksowania lub matematycznych, to chyba bardziej wydajne (a na pewno bardziej powszechne), aby wymusić wejście do być tablicą NumPy. Jest kilka fajnych funkcji umożliwiających szybkie wykonanie tego - co najważniejsze numpy.asarray. To pobiera dane wejściowe, nie robi nic, jeśli jest już tablicą, lub zawija dane wejściowe w tablicę, jeśli jest to lista, krotka itp., I opcjonalnie konwertuje ją na wybraną dtype. Jest więc bardzo szybki, gdy tylko jest to możliwe, i zapewnia, że ​​po prostu przyjmiesz, że dane wejściowe to tablica NumPy. Zwykle używamy nawet tej samej nazwy, ponieważ konwersja na tablicę nie spowoduje, że znajdzie się poza bieżącym zakresem :

x = numpy.asarray(x, dtype=numpy.double)

Sprawi to, że x.sizeczek zadziała we wszystkich przypadkach, które widzę na tej stronie.


62
Warto zauważyć, że nie jest to wada w Pythonie, ale celowe zerwanie kontraktu przez numpy- numpyjest biblioteką z bardzo konkretnym przypadkiem użycia i ma inną „naturalną” definicję prawdziwości tablicy Standard Python dla kontenerów. To ma sens, aby zoptymalizować dla tego przypadku, w sposób, który pathlibużywa /do łączenia ścieżek zamiast +- to nietypowe, ale ma sens w kontekście.
Gareth Latty

9
Zgoda. Chodzi mi o to, że ważne jest, aby pamiętać, że numpy zdecydowało się złamać pisanie kaczych zarówno dla bardzo powszechnych, jak if xi len(x)idiomów - a czasami to złamanie może być bardzo trudne do wykrycia i debugowania.
Mike

22
Nie wiem dla mnie, czy metoda o nazwie len (x) nie zwraca długości tablicy, ponieważ założenia, jej nazwa jest źle zaprojektowana.
Dalton,

11
To pytanie nie ma nic wspólnego z tablicami
numpy

19
@ppperry Tak, pierwotne pytanie nie dotyczyło tablic Numpy, ale podczas pracy z tymi i, być może, argumentami typu kaczego, pytanie to staje się bardzo istotne.
peterhil

222

Najlepszy sposób na sprawdzenie, czy lista jest pusta

Na przykład, jeśli przekazano następujące:

a = []

Jak sprawdzić, czy a jest pusty?

Krótka odpowiedź:

Umieść listę w kontekście logicznym (na przykład za pomocą instrukcji iflub while). Będzie sprawdzał, Falseczy jest pusty, i Trueinaczej. Na przykład:

if not a:                           # do this!
    print('a is an empty list')

PEP 8

PEP 8 , oficjalny przewodnik po języku Python dla kodu Python w standardowej bibliotece Pythona, zapewnia:

W przypadku sekwencji (ciągów, list, krotek) użyj faktu, że puste sekwencje są fałszywe.

Yes: if not seq:
     if seq:

No: if len(seq):
    if not len(seq):

Powinniśmy oczekiwać, że standardowy kod biblioteki powinien być tak wydajny i poprawny, jak to możliwe. Ale dlaczego tak jest i dlaczego potrzebujemy tych wskazówek?

Wyjaśnienie

Często widzę taki kod od doświadczonych programistów początkujących w Pythonie:

if len(a) == 0:                     # Don't do this!
    print('a is an empty list')

A użytkownicy leniwych języków mogą ulec pokusie:

if a == []:                         # Don't do this!
    print('a is an empty list')

Są poprawne w swoich odpowiednich językach. Jest to nawet semantycznie poprawne w Pythonie.

Ale uważamy to za nie-Pythonic, ponieważ Python obsługuje tę semantykę bezpośrednio w interfejsie obiektu listy za pomocą logicznego koercji.

Z dokumentów (i zwróć uwagę na włączenie pustej listy []):

Domyślnie obiekt jest uważany za prawdziwy, chyba że jego klasa definiuje __bool__()metodę zwracającą Falselub __len__()metodę zwracającą zero, gdy zostanie wywołana z obiektem. Oto większość wbudowanych obiektów uznanych za fałszywe:

  • stałe zdefiniowane jako fałsz: Nonei False.
  • zera każdego typu numerycznej 0, 0.0, 0j, Decimal(0),Fraction(0, 1)
  • Puste sekwencje i kolekcje: '', (), [], {}, set(),range(0)

Oraz dokumentacja modelu danych:

object.__bool__(self)

Wezwany do wdrożenia testowania wartości prawdy i wbudowanej operacji bool(); powinien wrócić Falselub True. Gdy ta metoda nie jest zdefiniowana, __len__()jest wywoływana, jeśli jest zdefiniowana, a obiekt jest uważany za prawdziwy, jeśli jego wynik jest niezerowy. Jeśli klasa nie definiuje ani, __len__() ani __bool__()wszystkie jej instancje są uważane za prawdziwe.

i

object.__len__(self)

Wywoływany w celu wdrożenia wbudowanej funkcji len(). Powinna zwracać długość obiektu, liczba całkowita> = 0. Również obiekt, który nie definiuje __bool__()metody i którego __len__()metoda zwraca zero, jest uważany za fałsz w kontekście boolowskim.

Zamiast tego:

if len(a) == 0:                     # Don't do this!
    print('a is an empty list')

albo to:

if a == []:                     # Don't do this!
    print('a is an empty list')

Zrób to:

if not a:
    print('a is an empty list')

Robienie tego, co Pythonic zwykle się opłaca:

Czy to się opłaca? (Pamiętaj, że krótszy czas na wykonanie równoważnej operacji jest lepszy :)

>>> import timeit
>>> min(timeit.repeat(lambda: len([]) == 0, repeat=100))
0.13775854044661884
>>> min(timeit.repeat(lambda: [] == [], repeat=100))
0.0984637276455409
>>> min(timeit.repeat(lambda: not [], repeat=100))
0.07878462291455435

Dla skali, oto koszt wywołania funkcji oraz zbudowania i zwrócenia pustej listy, którą możesz odjąć od kosztów kontroli pustki użytych powyżej:

>>> min(timeit.repeat(lambda: [], repeat=100))
0.07074015751817342

Widzimy, że albo sprawdzanie na długości za pomocą funkcji wbudowanej lenw porównaniu do 0 lub sprawdzenie przed pustym liście jest znacznie mniej wydajnych niż przy użyciu składni wbudowanego języka jako udokumentowane.

Dlaczego?

Do len(a) == 0kontroli:

Najpierw Python musi sprawdzić globale, aby zobaczyć, czy lenjest zacieniony.

Następnie musi wywołać funkcję, załadować 0i wykonać porównanie równości w Pythonie (zamiast z C):

>>> import dis
>>> dis.dis(lambda: len([]) == 0)
  1           0 LOAD_GLOBAL              0 (len)
              2 BUILD_LIST               0
              4 CALL_FUNCTION            1
              6 LOAD_CONST               1 (0)
              8 COMPARE_OP               2 (==)
             10 RETURN_VALUE

Aby to [] == []zrobić, musi zbudować niepotrzebną listę, a następnie ponownie wykonać operację porównania na maszynie wirtualnej Pythona (w przeciwieństwie do C)

>>> dis.dis(lambda: [] == [])
  1           0 BUILD_LIST               0
              2 BUILD_LIST               0
              4 COMPARE_OP               2 (==)
              6 RETURN_VALUE

Sposób „Pythonic” jest znacznie prostszym i szybszym sprawdzaniem, ponieważ długość listy jest buforowana w nagłówku instancji obiektu:

>>> dis.dis(lambda: not [])
  1           0 BUILD_LIST               0
              2 UNARY_NOT
              4 RETURN_VALUE

Dowody ze źródła C i dokumentacji

PyVarObject

To rozszerzenie PyObjectdodaje ob_sizepole. Jest to używane tylko w przypadku obiektów o pewnym znaczeniu długości. Ten typ często nie pojawia się w interfejsie API języka Python / C. Odpowiada polom zdefiniowanym przez rozwinięcie PyObject_VAR_HEADmakra.

Ze źródła c w pliku Include / listobject.h :

typedef struct {
    PyObject_VAR_HEAD
    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
    PyObject **ob_item;

    /* ob_item contains space for 'allocated' elements.  The number
     * currently in use is ob_size.
     * Invariants:
     *     0 <= ob_size <= allocated
     *     len(list) == ob_size

Odpowiedź na komentarze:

By wskazać, że jest to również prawdziwe w odniesieniu do Niepuste przypadku chociaż jest dość brzydka przy l=[]czym %timeit len(l) != 090,6 NS NS ± 8,3, %timeit l != []55,6 ± 3,09 ns, %timeit not not l38,5 ± 0,372 ns. Ale nie ma mowy, aby ktokolwiek mógł się cieszyć not not lpomimo potrójnej prędkości. To wygląda niedorzecznie. Ale prędkość wygrywa.
Przypuszczam, że problem polega na testowaniu z czasem, ponieważ if l:jest po prostu wystarczający, ale zaskakująco %timeit bool(l)daje 101 ns ± 2,64 ns. Ciekawe, że bez tej kary nie można zmusić do buntu. %timeit ljest bezużyteczny, ponieważ nie nastąpiłaby konwersja.

Magia IPython %timeitnie jest tutaj całkowicie bezużyteczna:

In [1]: l = []                                                                  

In [2]: %timeit l                                                               
20 ns ± 0.155 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

In [3]: %timeit not l                                                           
24.4 ns ± 1.58 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [4]: %timeit not not l                                                       
30.1 ns ± 2.16 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Widzimy tutaj trochę liniowego kosztu każdego dodatkowego not. Chcemy, aby koszty, ceteris paribus , to znaczy wszystkie inne były równe - gdzie wszystko inne jest zminimalizowane w największym możliwym stopniu:

In [5]: %timeit if l: pass                                                      
22.6 ns ± 0.963 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [6]: %timeit if not l: pass                                                  
24.4 ns ± 0.796 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [7]: %timeit if not not l: pass                                              
23.4 ns ± 0.793 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Teraz spójrzmy na przypadek niepustej listy:

In [8]: l = [1]                                                                 

In [9]: %timeit if l: pass                                                      
23.7 ns ± 1.06 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [10]: %timeit if not l: pass                                                 
23.6 ns ± 1.64 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [11]: %timeit if not not l: pass                                             
26.3 ns ± 1 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Widzimy tutaj, że nie ma większego znaczenia, czy przekazujesz rzeczywiste boolsprawdzenie stanu, czy samą listę, a jeśli tak, to podanie listy, tak jak jest, jest szybsze.

Python jest napisany w C; używa swojej logiki na poziomie C. Wszystko, co napiszesz w Pythonie, będzie wolniejsze. I prawdopodobnie będzie to rząd wielkości wolniejszy, chyba że użyjesz mechanizmów wbudowanych bezpośrednio w Pythona.


By wskazać, że jest to również prawdziwe w odniesieniu do Niepuste przypadku chociaż jest dość brzydka przy l=[]czym %timeit len(l) != 090,6 NS NS ± 8,3, %timeit l != []55,6 ± 3,09 ns, %timeit not not l38,5 ± 0,372 ns. Ale nie ma mowy, aby ktokolwiek mógł się cieszyć not not lpomimo potrójnej prędkości. To wygląda niedorzecznie. Ale prędkość wygrywa
Gregory Morse

Przypuszczam, że problem polega na testowaniu z czasem, ponieważ if l:jest po prostu wystarczający, ale zaskakująco %timeit bool(l)daje 101 ns ± 2,64 ns. Ciekawe, że bez tej kary nie można zmusić do buntu. %timeit ljest bezużyteczny, ponieważ nie nastąpiłaby konwersja.
Gregory Morse

138

Pusta lista sama w sobie jest uważana za fałszywą podczas testowania prawdziwej wartości (patrz dokumentacja Pythona ):

a = []
if a:
     print "not empty"

@Daren Thomas

EDYCJA: Kolejny argument przeciwko testowaniu pustej listy jako False: A co z polimorfizmem? Nie powinieneś polegać na tym, że lista jest listą. Powinien po prostu kwakać jak kaczka - jak zamierzasz nakłonić swoją kaczkę do kolekcjonowania „Fałszywego”, gdy nie ma żadnych elementów?

Twój duckCollection powinny wdrożyć __nonzero__lub __len__więc jeśli: będzie działać bez problemów.


Dziwne, jak [] == Falseoceni się na False
information_interchange

@information_interchange Jeśli chcesz jawnie sprawdzić prawdziwość wartości, użyj bool(). bool([]) == Falseoceni Truezgodnie z oczekiwaniami.
sierpień

103

Odpowiedź Patryka (zaakceptowana) jest słuszna: if not a:jest właściwym sposobem na zrobienie tego. Odpowiedź Harleya Holcombe jest słuszna, że ​​jest to w przewodniku po stylu PEP 8. Ale żadna z odpowiedzi nie wyjaśnia, dlaczego dobrym pomysłem jest podążanie za tym idiomem - nawet jeśli osobiście uznasz, że nie jest on wystarczająco wyraźny lub mylący dla użytkowników Ruby lub cokolwiek innego.

Kod Python i społeczność Python mają bardzo silne idiomy. Przestrzeganie tych idiomów ułatwia czytanie kodu każdemu, kto ma doświadczenie w Pythonie. A kiedy naruszasz te idiomy, to silny sygnał.

Prawdą jest, że if not a:nie rozróżnia pustych list None, ani liczbowego 0, pustych krotek, pustych typów kolekcji utworzonych przez użytkownika, ani pustych typów kolekcji, które nie zostały stworzone przez użytkownika, lub tablicy NumPy z jednym elementem działającej jako skalary z falsey wartości itp. Czasami ważne jest, aby o tym wyraźnie mówić. W takim przypadku wiesz, co chcesz wyrazić, więc możesz dokładnie to sprawdzić. Na przykład if not a and a is not None:oznacza „cokolwiek falsey z wyjątkiem Brak”, podczas gdy if len(a) != 0:oznacza „tylko puste sekwencje - a wszystko oprócz sekwencji jest tutaj błędem” i tak dalej. Oprócz testowania dokładnie tego, co chcesz przetestować, oznacza to również dla czytelnika, że ​​ten test jest ważny.

Ale kiedy nie masz nic do wyrażenia, coś innego niż if not a:wprowadza czytelnika w błąd. Sygnalizujesz coś tak ważnego, kiedy tak nie jest. (Można również czyni kod mniej elastyczne, lub wolniej, czy cokolwiek, ale to wszystko mniej ważne.) A jeśli zwykle zmylić czytelnika tak, to kiedy zrobić trzeba dokonać rozróżnienia, to przejdzie niezauważone, ponieważ „płakałeś wilka” w całym kodzie.


78

Po co w ogóle sprawdzać?

Wydaje się, że nikt nie zajął się kwestionowaniem potrzeby przetestowania listy. Ponieważ nie podałeś żadnego dodatkowego kontekstu, mogę sobie wyobrazić, że może nie będziesz musiał tego sprawdzać w pierwszej kolejności, ale nie znasz przetwarzania list w Pythonie.

Twierdziłbym, że najbardziej pythonicznym sposobem jest w ogóle nie sprawdzanie, a po prostu przetworzenie listy. W ten sposób zrobi to dobrze, czy to puste, czy pełne.

a = []

for item in a:
    <do something with item>

<rest of code>

Ma to tę zaletę obsługi wszelkich treści , jednocześnie nie wymagając czek specyficzny dla pustki. Jeśli a jest puste, blok zależny nie zostanie wykonany, a tłumacz przejdzie do następnego wiersza.

Jeśli rzeczywiście potrzebujesz sprawdzić tablicę pod kątem pustki, pozostałe odpowiedzi są wystarczające.


3
Rzecz w tym, że sprawdzenie, czy lista jest pusta, jest dość ważne, przynajmniej dla mnie. Czy zastanawiałeś się, czy w środku jest jakiś skrypt, <rest of code>który mógłby wykorzystać wynik z forpętli? Lub bezpośrednio użyć niektórych wartości w a? Rzeczywiście, jeśli skrypt jest zaprojektowany do działania przy ściśle kontrolowanych danych wejściowych, sprawdzenie może być trochę niepotrzebne. Ale w większości przypadków dane wejściowe są różne, a sprawdzenie jest zwykle lepsze.
Amarth Gûl

Z szacunkiem nie. Uznałem, że ktoś, kto nie wiedział wystarczająco dużo o Pythonie, aby wiedzieć, że „jeśli <lista>:” jest prawidłową odpowiedzią, zapytał, jak sprawdzić pustą listę. Potem zauważam Mnóstwo odpowiedzi, które przedstawiają odmienne opinie, ale żadna nie wydaje się odpowiadać pierwotnej potrzebie. Właśnie to starałem się zrobić z moją odpowiedzią - poproś, aby zbadali potrzebę przed kontynuowaniem. Uważam, że wprost zasugerowałem tyle samo w mojej odpowiedzi.
MrWonderful

@ AmarthGûl - W jaki sposób można uzyskać wyniki z pętli for do skryptu wewnątrz <reszty kodu> do przetworzenia? Może na liście? A może dykt? Jeśli tak, obowiązuje ta sama logika. Nie rozumiem, w jaki sposób zmienne dane wejściowe mogą mieć jakikolwiek wpływ w ramach każdego rozsądnie zaprojektowanego kodu, w którym przetwarzanie pustej listy byłoby złym pomysłem.
MrWonderful

Trochę stary, ale jeśli tylko sprawdzałeś, czy lista jest pusta, w przypadku niepustej listy kod powtarza proces w kółko, gdy OP po prostu szuka operacji sprawdzania. Wyobraź sobie gorszy scenariusz dla tego kodu, gdy n zbliża się do nieskończoności ...
DJK

7
@DJK - Nie, myślę, że nadal go brakuje. Prawdopodobnie chcesz zrobić coś z listą, jeśli ją masz. Co zrobiłbyś inaczej, gdyby był pusty? Wrócić wcześnie? Co jeśli nie jest pusty? przetworzyć to? Chodzi o to, że prawdopodobnie nie musisz sprawdzać pustej listy, po prostu iteruj ją i rób wszystko, co chcesz zrobić z elementami. Jeśli nie ma żadnych elementów, przewracasz się. Jeśli są elementy, przetwarzasz je tak, jak potrzebujesz. Chodzi o to, aby NIE używać przykładu DLA pustego czeku, ale raczej wcale NIE sprawdzać, wystarczy przetworzyć listę.
MrWonderful


40

Napisałem:

if isinstance(a, (list, some, other, types, i, accept)) and not a:
    do_stuff

która została przegłosowana -1. Nie jestem pewien, czy to dlatego, że czytelnicy sprzeciwiali się strategii lub uważali, że odpowiedź nie była pomocna, jak przedstawiono. Udam, że to ten drugi, ponieważ --- cokolwiek liczy się jako „pytoniczne” --- to jest poprawna strategia. O ile już nie wykluczono lub nie jesteś przygotowany do obsługi przypadków, w których ana przykład Falsepotrzebujesz testu bardziej restrykcyjnego niż tylko if not a:. Możesz użyć czegoś takiego:

if isinstance(a, numpy.ndarray) and not a.size:
    do_stuff
elif isinstance(a, collections.Sized) and not a:
    do_stuff

pierwszy test jest odpowiedzią na odpowiedź @ Mike'a powyżej. Trzeci wiersz można również zastąpić:

elif isinstance(a, (list, tuple)) and not a:

jeśli chcesz zaakceptować tylko wystąpienia poszczególnych typów (i ich podtypów) lub za pomocą:

elif isinstance(a, (list, tuple)) and not len(a):

Możesz uciec bez jawnego sprawdzania typu, ale tylko wtedy, gdy otaczający kontekst już cię zapewnia, że ajest to wartość typów, na które jesteś przygotowany, lub jeśli masz pewność, że typy, na które nie jesteś przygotowany, będą do zgłaszania błędów (np. TypeErrorwywołania lenwartości, dla której jest niezdefiniowana), którą jesteś gotowy obsłużyć. Ogólnie rzecz biorąc, konwencje „pytoniczne” wydają się iść w tę ostatnią stronę. Ściśnij go jak kaczkę i pozwól mu podnieść DuckError, jeśli nie wie jak walić. Nadal musisz zastanowić się, jakie przyjmujesz założenia i czy przypadki, do których nie jesteś przygotowany właściwie się zabrać, naprawdę popełniają błąd w odpowiednich miejscach. Tablice Numpy są dobrym przykładem, na którym polegają ślepolen lub typ logiczny może nie robić dokładnie tego, czego oczekujesz.


3
Bardzo rzadko masz wyczerpującą listę 6 typów, które chcesz zaakceptować i nie być elastycznym dla innych typów. Kiedy potrzebujesz tego rodzaju rzeczy, prawdopodobnie potrzebujesz ABC. W tym przypadku prawdopodobnie byłby to jeden ze standardowych ABC, takich jak collections.abc.Sizedlub collections.abc.Sequence, ale może to być ten, w którym piszesz sam register(list). Jeśli rzeczywiście masz kod, w którym ważne jest odróżnienie pustego od innego falsey, a także odróżnienie list i krotek od innych sekwencji, to jest to poprawne - ale nie sądzę, że masz taki kod.
abarnert

13
Ludzie nie lubią tego, ponieważ w większości przypadków jest to całkowicie pozbawione znaczenia. Python jest językiem kaczym, a ten poziom kodowania obronnego aktywnie to utrudnia. Idea systemu typu Python polega na tym, że wszystko powinno działać tak długo, jak długo obiekt przechodzi w funkcji w sposób, w jaki musi. Wykonując jawne kontrole typów, zmuszasz osobę dzwoniącą do używania określonych typów, co jest sprzeczne z samą ziarnistością języka. Chociaż czasami takie rzeczy są konieczne (wyłączając ciągi traktowane jako sekwencje), takie przypadki są rzadkie i prawie zawsze najlepsze jako czarne listy.
Gareth Latty

1
Jeśli naprawdę chcesz sprawdzić, czy wartość jest dokładnie, []a nie czymś fałszywym innego rodzaju, to na pewno if a == []:jest to wymagane , zamiast zastanawiać się nad isinstance .
RemcoGerlich,

2
==Jednak istnieją pewne automatyczne przymusy . Z czubka mojej głowy nie mogę zidentyfikować żadnego []. [] == ()na przykład zwraca False. Ale na przykład frozenset()==set()powraca True. Warto więc przynajmniej zastanowić się, czy jakiś niepożądany typ może być zmuszony [](lub odwrotnie) podczas działania a == [].
dubiousjim

@RemcoGerlich - isinstance () jest nadal lepszym rozwiązaniem niż tworzenie pustej listy do porównania. Ponadto, jak zauważył inny, operator równości może odwoływać się do niejawnej konwersji niektórych typów, co może być niepożądane. Nie ma powodu, aby kiedykolwiek kodować „a == []”, a kod ten byłby zdecydowanie oznaczony jako usterka w każdej recenzji kodu, w której uczestniczyłem. Używanie odpowiedniego narzędzia dostarczonego przez język nie powinno być uważane za , ale raczej „dobra technika programowania”.
MrWonderful,

29

Z dokumentacji dotyczącej testowania wartości prawdy:

Uwzględniane są wszystkie wartości inne niż wymienione tutaj True

  • None
  • False
  • zera każdego typu liczbowa, na przykład 0, 0.0, 0j.
  • pustych kolejności, na przykład '', (), [].
  • dowolne puste mapowanie, na przykład {}.
  • instancje klas zdefiniowanych przez użytkownika, jeśli klasa definiuje metodę __bool__()lub __len__(), gdy ta metoda zwraca wartość całkowitą zero lub wartość bool False.

Jak widać, pusta lista []jest fałszem , więc robienie tego, co byłoby zrobione z wartością logiczną, brzmi najbardziej efektywnie:

if not a:
    print('"a" is empty!')

@DJ_Stuffy_K stwierdzam, co w testach jednostkowych pusta lista? Po prostu użyj assert(not myList). Jeśli chcesz również stwierdzić, że obiekt jest list, możesz użyć assertIsInstance().
Sнаđошƒаӽ

24

Oto kilka sposobów sprawdzenia, czy lista jest pusta:

a = [] #the list

1) Dość prosty pythonowy sposób:

if not a:
    print("a is empty")

W Pythonie puste pojemniki, takie jak listy, krotki, zestawy, dykty, zmienne itp. Są postrzegane jako False. Można po prostu traktować listę jako predykat ( zwracającą wartość logiczną ). A Truewartość wskazuje, że nie jest pusta.

2) Bardzo wyraźny sposób: używając, len()aby znaleźć długość i sprawdzić, czy jest ona równa 0:

if len(a) == 0:
    print("a is empty")

3) Lub porównanie z anonimową pustą listą:

if a == []:
    print("a is empty")

4) Innym, ale głupim sposobem jest użycie exceptioni iter():

try:
    next(iter(a))
    # list has elements
except StopIteration:
    print("Error: a is empty")

20

Wolę następujące:

if a == []:
   print "The list is empty."

37
Będzie to wolniejsze, ponieważ niepotrzebnie tworzysz dodatkową pustą listę.
Carl Meyer,

32
jest to mniej czytelne if not a:i łatwiej się psuje. Proszę nie rób tego.
devsnd

Dobrze jest powiedzieć, że wcześniej () == []jest równa fałszowi. Chociaż podoba mi się to, jak ta implementacja odczytuje if not a:wszystkie przypadki, jeśli zdecydowanie oczekujesz listy, twój przykład powinien wystarczyć.
A Star

19

Metoda 1 (preferowana):

if not a : 
   print ("Empty") 

Metoda 2:

if len(a) == 0 :
   print( "Empty" )

Metoda 3:

if a == [] :
  print ("Empty")

12
def list_test (L):
    if   L is None  : print('list is None')
    elif not L      : print('list is empty')
    else: print('list has %d elements' % len(L))

list_test(None)
list_test([])
list_test([1,2,3])

Czasami dobrze jest badać Noneosobno i dla pustki, ponieważ są to dwa różne stany. Powyższy kod generuje następujące dane wyjściowe:

list is None 
list is empty 
list has 3 elements

Chociaż to nic nie warte Nonejest fałszu. Więc jeśli nie chcesz rozdzielać testu dla None-ness, nie musisz tego robić.

def list_test2 (L):
    if not L      : print('list is empty')
    else: print('list has %d elements' % len(L))

list_test2(None)
list_test2([])
list_test2([1,2,3])

produkuje oczekiwany

list is empty
list is empty
list has 3 elements

8

Podano wiele odpowiedzi, a wiele z nich jest całkiem dobrych. Chciałem tylko dodać tę czek

not a

przejdzie również Nonei inne rodzaje pustych struktur. Jeśli naprawdę chcesz sprawdzić pustą listę, możesz to zrobić:

if isinstance(a, list) and len(a)==0:
    print("Received an empty list")

Możliwe, że zgłasza to wyjątek, jeśli anie jest listą i anie ma __len__zaimplementowanej metody . Poleciłbym:if isinstance(obj, list): if len(obj) == 0: print '...'
Sven Krüger

4
@ SvenKrüger nope. Operator andjest leniwy w Pythonie. Nic późniejszego andnie zostanie wykonane, jeśli warunek wcześniejszy andjest False.
ElmoVanKielmo

7

moglibyśmy użyć prostego, jeśli inaczej:

item_list=[]
if len(item_list) == 0:
    print("list is empty")
else:
    print("list is not empty")

5
-1 - Aby uniknąć nieporozumień, nie używaj słów zarezerwowanych dla nazw zmiennych, ponieważ może się to zdarzyć zaskakująco przy następnej próbie wywołania, na przykład „list ()” ... coś w rodzaju „TypeError: obiekt„ list ”to niewymagalne ”czy coś takiego.
MrWonderful

6

Jeśli chcesz sprawdzić, czy lista jest pusta:

l = []
if l:
    # do your stuff.

Jeśli chcesz sprawdzić, czy wszystkie wartości na liście są puste. Będzie to Truejednak dotyczyło pustej listy:

l = ["", False, 0, '', [], {}, ()]
if all(bool(x) for x in l):
    # do your stuff.

Jeśli chcesz używać obu przypadków jednocześnie:

def empty_list(lst):
    if len(lst) == 0:
        return False
    else:
        return all(bool(x) for x in l)

Teraz możesz użyć:

if empty_list(lst):
    # do your stuff.

1
all (bool (x) dla
xwl

5

Zainspirowany rozwiązaniem @ dubiousjim, proponuję zastosować dodatkowe ogólne sprawdzenie, czy jest to coś iterowalnego

import collections
def is_empty(a):
    return not a and isinstance(a, collections.Iterable)

Uwaga: ciąg uważa się za iterowalny. - Dodajand not isinstance(a,(str,unicode)) jeśli chcesz, aby pusty ciąg został wykluczony

Test:

>>> is_empty('sss')
False
>>> is_empty(555)
False
>>> is_empty(0)
False
>>> is_empty('')
True
>>> is_empty([3])
False
>>> is_empty([])
True
>>> is_empty({})
True
>>> is_empty(())
True

1
Za granicą; to tylko pytanie, czy lista jest pusta, a nie czy coś jest pustą iterowalną.
pppery

1
Gdybym nie był zadowolony if a:, to dlatego, że chciałem wyjątku, jeśli anie byłby to jakiś pojemnik. (Bycie iterowalnym pozwala również na iteratory, których nie można z powodzeniem przetestować pod kątem pustki.)
Davis Herring,

5
print('not empty' if a else 'empty')

trochę bardziej praktyczne:

a.pop() if a else None

i wersja shertest:

if a: a.pop() 

4

Od Python3 możesz używać

a == []

aby sprawdzić, czy lista jest pusta

EDYCJA: Działa to również z python2.7.

Nie jestem pewien, dlaczego jest tak wiele skomplikowanych odpowiedzi. To całkiem jasne i proste


1
proszę podać więcej wyjaśnień na temat tego, jak to działa bez pisania „jeśli”?
ganeshdeshmukh

3
To nie jest pythoniczny ani kompletny przykład. Ponadto tworzy instancję pustej listy przy każdym napotkaniu. Nie rób tego
MrWonderful

@MrWonderful nie tworzy za każdym razem pustej listy. Po prostu sprawdza, czy istniejąca lista ajest pusta, czy nie.
Tessaracter

@MrWonderful Nie rozumiem, co sprawia, że ​​jestpythonic
Tessaracter

@ganeshdeshmukh, jeśli a==[]go użyjesz , wypisze true na terminalu python, jeśli a jest puste. W przeciwnym razie wydrukuje False. Możesz użyć tego wewnątrz warunku if również jakoif(a==[])
Tessaracter

3

Możesz nawet spróbować użyć bool () w ten sposób

    a = [1,2,3];
    print bool(a); # it will return True
    a = [];
    print bool(a); # it will return False

Uwielbiam ten sposób sprawdzania, czy lista jest pusta, czy nie.

Bardzo przydatny i użyteczny.


4
Dla tych (jak ja), którzy nie wiedzieli, bool()konwertuje zmienną Pythona na wartość logiczną, dzięki czemu można przechowywać prawdziwość lub fałsz wartości bez konieczności użycia instrukcji if. Myślę, że jest mniej czytelny niż zwykłe użycie warunku, takiego jak zaakceptowana odpowiedź, ale jestem pewien, że istnieją inne dobre przypadki użycia.
Galen Long

Jest to użyteczne w wyrażeniu i jest bardziej zwięzłe.
qneill,

3

Wystarczy użyć is_empty () lub uczynić funkcję taką jak: -

def is_empty(any_structure):
    if any_structure:
        print('Structure is not empty.')
        return True
    else:
        print('Structure is empty.')
        return False  

Może być używany do dowolnej struktury danych, takiej jak lista, krotki, słownik i wiele innych. Dzięki nim możesz wywoływać go wiele razy za pomocą just is_empty(any_structure).


3
Nazwa is_emptysugeruje, że coś zwraca. Ale gdyby tak się stało, byłoby to po prostu coś bool(any_structure), czego powinieneś użyć ( kiedybool w ogóle potrzebujesz ).
Davis Herring,

4
Dlaczego chcemy, aby odmiana polegała na booltym, że (także) drukuje komunikaty na standardowe wyjście?
Davis Herring,

@DavisHerring Zawsze zawsze mamy dwa wyjścia, aby wydrukować za pomocą funkcji, inna używa boolzmiennej return . Wybór należy do Ciebie. Piszę oba, abyście mogli wybierać między nimi.
Vineet Jain,

3

Prostym sposobem jest sprawdzenie, czy długość jest równa zero.

if len(a) == 0:
    print("a is empty")

1

Prawdą jest, Falseże pusta lista jest prawdą, podczas gdy dla niepustej listy jest to prawda True.


1

To, co mnie tu sprowadziło, to szczególny przypadek użycia: tak naprawdę chciałem, aby funkcja powiedziała mi, czy lista jest pusta, czy nie. Chciałem uniknąć pisania tutaj własnej funkcji lub używania wyrażenia lambda (ponieważ wydawało się, że powinna być dość prosta):

foo = itertools.takewhile(is_not_empty, (f(x) for x in itertools.count(1)))

I oczywiście jest to bardzo naturalny sposób:

foo = itertools.takewhile(bool, (f(x) for x in itertools.count(1)))

Oczywiście nie należy używać boolw if(tj. if bool(L):), Ponieważ jest to dorozumiane. Jednak w przypadkach, gdy „funkcja nie jest pusta” jest wyraźnie potrzebna jako funkcja, booljest najlepszym wyborem.


1

Aby sprawdzić, czy lista jest pusta, możesz użyć dwóch poniższych sposobów. Pamiętaj jednak, że powinniśmy unikać sposobu jawnego sprawdzania rodzaju sekwencji (jest toless pythonic sposób):

def enquiry(list1): 
    if len(list1) == 0: 
        return 0
    else: 
        return 1

# ––––––––––––––––––––––––––––––––

list1 = [] 

if enquiry(list1): 
    print ("The list isn't empty") 
else: 
    print("The list is Empty") 

# Result: "The list is Empty".

Drugi sposób to more pythonic jeden. Ta metoda jest domyślnym sposobem sprawdzania i jest znacznie bardziej preferowana niż poprzednia.

def enquiry(list1): 
    if not list1: 
        return True
    else: 
        return False

# ––––––––––––––––––––––––––––––––

list1 = [] 

if enquiry(list1): 
    print ("The list is Empty") 
else: 
    print ("The list isn't empty") 

# Result: "The list is Empty"

Mam nadzieję że to pomoże.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.