Come posso verificare se un elenco è vuoto?


3234

Ad esempio, se superato quanto segue:

a = []

Come posso verificare se aè vuoto?

Risposte:


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

Usare l' implicita booleanness del vuoto listè piuttosto pitonico.


1130
Interpretando l'avvocato del diavolo. Non capisco perché questo idioma sia considerato pitonico. "Esplicito è meglio che implicito", giusto? Questo controllo non sembra molto esplicito su ciò che sta controllando.
James McMahon,

222
@JamesMcMahon - è un compromesso tra esplicito e flessibilità del tipo. in generale, "essere espliciti" significa non fare cose "magiche". d'altra parte, "digitare anatra" significa lavorare con interfacce più generali, piuttosto che controllare esplicitamente i tipi. quindi qualcosa come if a == []forzare un tipo particolare ( () == []è False). qui, il consenso generale sembra essere che la tipizzazione delle anatre vince (in effetti, dicendo che __nonzero__è l'interfaccia per testare il vuoto docs.python.org/reference/datamodel.html#object.__nonzero__ )
Andrew Cooke

38
Questo metodo non funziona su matrici intorpidite .. quindi penso che len (a) == 0 sia preferibile sia in termini di "typing anatra" che implicito.
Mr.WorshipMe

10
Il modo canonico di sapere se un array in C è vuoto è sotto-dereferenziando il primo elemento e vedendo se è nullo, assumendo un array che è nul-terminato. Altrimenti, confrontarne la lunghezza con zero è assolutamente inefficiente se l'array ha dimensioni significative. Inoltre, in genere, non allocare memoria per un array vuoto (il puntatore rimane nullo), quindi non ha senso tentare di ottenerne la lunghezza. Non sto dicendo che len (a) == 0 non sia un buon modo per farlo, semplicemente non mi urla "C" quando lo vedo.
slitta

6
@BrennenSprimont, Se non ha una terminazione nulla, allora conosci già la lunghezza, sia che sia memorizzata in una variabile separata o che l'array sia avvolto in un contenitore che ne tiene traccia. C ++, Java, C # hanno tali contenitori e implementano in modo efficiente un metodo "lunghezza". C non ha una cosa del genere , devi farlo da solo. Le matrici C allocate staticamente sono solo dei puntatori a uno spazio di memoria che è garantito per avere spazio sufficiente per memorizzare la quantità di dati richiesti. Non c'è niente incorporato in C che ti farà sapere quanto hai già riempito quello spazio.
slitta,

1160

Il modo pitone per farlo è dalla guida di stile PEP 8 (dove significa "consigliato" e No significa "non raccomandato"):

Per le sequenze (stringhe, elenchi, tuple), usa il fatto che le sequenze vuote sono false.

Yes: if not seq:
     if seq:

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

49
Il secondo modo sembra migliore se si desidera segnalare che seqsi prevede che sia una sorta di oggetto simile a un elenco.
BallpointBen,

5
@BallpointBen che, direbbero i sostenitori del Pythonism, dovrebbe essere implicito nel modo in cui la variabile viene nominata, per quanto possibile
axolotl

9
@BallpointBen prova a usare l' hint di tipo Python per segnalare quale dovrebbe essere una variabile. È stato introdotto in 3.5.
Boris,

8
numpy ha rotto questo idioma ... seq = numpy.array ([1,2,3]) seguito da se non seq solleva un'eccezione "ValueError: il valore di verità di un array con più di un elemento è ambiguo. Usa a.any () or a.all () "
Mr.WorshipMe

2
@jeronimo: credo che sia un avvertimento specifico per lxml.
Harley Holcombe,

769

Lo preferisco esplicitamente:

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

In questo modo è chiaro al 100% che liè una sequenza (elenco) e vogliamo testarne le dimensioni. Il mio problema if not li: ...è che dà la falsa impressione che lisia una variabile booleana.


91
Controllare se la lunghezza di una lista è uguale a zero, piuttosto che controllare se la lista è falsa, è brutta e non sintonica. Chiunque abbia familiarità con Python non penserà affatto di liessere un bool e non se ne preoccuperà. Se è importante, dovresti aggiungere un commento, non più codice.
Carl Smith,

21
Questo sembra un test inutilmente preciso, che è spesso più lento ed è sempre meno leggibile IMHO. Invece di controllare la dimensione di qualcosa di vuoto, perché non controllare se è vuoto?
Giovanni B,

34
Ad ogni modo, il motivo per cui questo è negativo (e che violare idiomi in una lingua con forti idiomi come Python in genere è negativo) è che segnala al lettore che stai controllando specificamente la lunghezza per qualche motivo (ad esempio, perché vuoi Noneo 0per sollevare un'eccezione anziché passare). Così, quando lo si fa senza motivo, che è fuorviante, e significa anche che quando il codice non necessità di fare la distinzione, la distinzione è invisibile perché hai "lupo Cried" in tutto il resto della fonte.
abarnert,

18
Penso che questo stia allungando inutilmente il codice. Altrimenti, perché non essere ancora più "esplicito" con if bool(len(li) == 0) is True:?
Augurar

11
@Jabba sarà O (1) in molti casi (quelli in cui lavori con i tipi di dati integrati), ma non puoi fare affidamento su questo. Potresti lavorare con un tipo di dati personalizzato che non ha questa proprietà. Potresti anche decidere di aggiungere questo tipo di dati personalizzato in un secondo momento, dopo aver già scritto questo codice.
ralokt,

325

Questo è il primo hit di Google per "test array vuoto di python" e query simili, inoltre altre persone sembrano generalizzare la domanda oltre le semplici liste, quindi ho pensato di aggiungere un avvertimento per un diverso tipo di sequenza che molte persone potrebbe usare.

Altri metodi non funzionano per gli array NumPy

È necessario fare attenzione con le matrici NumPy, poiché altri metodi che funzionano correttamente per lists o altri contenitori standard non funzionano per le matrici NumPy. Spiego perché di seguito, ma in breve, il metodo preferito è quello di utilizzare size.

Il modo "pythonic" non funziona: Parte 1

Il modo "pythonic" fallisce con gli array NumPy perché NumPy tenta di eseguire il cast dell'array in un array di bools e if xcerca di valutare tutti questi bools contemporaneamente per un qualche valore di verità aggregato. Ma questo non ha alcun senso, quindi ottieni un 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()

Il modo "pythonic" non funziona: Parte 2

Ma almeno il caso sopra ti dice che è fallito. Se ti capita di avere un array NumPy con esattamente un elemento, l' ifistruzione "funzionerà", nel senso che non ricevi un errore. Tuttavia, se quell'elemento risulta essere 0(o 0.0, o False, ...), l' ifistruzione genererà erroneamente False:

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

Ma chiaramente xesiste e non è vuoto! Questo risultato non è quello che volevi.

L'uso lenpuò dare risultati inaspettati

Per esempio,

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

restituisce 1, anche se l'array ha zero elementi.

Il modo numpythonic

Come spiegato nelle FAQ di SciPy , il metodo corretto in tutti i casi in cui sai di avere un array NumPy è usare 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

Se non si è sicuri che possa essere un listarray NumPy o qualcos'altro, è possibile combinare questo approccio con la risposta fornita da @dubiousjim per assicurarsi che venga utilizzato il test giusto per ciascun tipo. Non molto "pitonico", ma si scopre che NumPy ha intenzionalmente rotto la pitonicità almeno in questo senso.

Se devi fare di più che controllare se l'input è vuoto e stai usando altre funzionalità di NumPy come indicizzazione o operazioni matematiche, è probabilmente più efficiente (e sicuramente più comune) forzare l'input a essere un array NumPy. Ci sono alcune funzioni utili per farlo rapidamente, soprattutto numpy.asarray. Questo prende il tuo input, non fa nulla se è già un array o avvolge il tuo input in un array se è un elenco, una tupla, ecc. E facoltativamente lo converte nel tuo prescelto dtype. Quindi è molto veloce ogni volta che può essere e ti assicura che devi solo supporre che l'input sia un array NumPy. Di solito usiamo anche lo stesso nome, poiché la conversione in un array non lo farà tornare al di fuori dell'ambito corrente :

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

Questo farà funzionare il x.sizecontrollo in tutti i casi che vedo in questa pagina.


62
Vale la pena notare che questo non è un difetto in Python, ma piuttosto una rottura intenzionale del contratto da parte di numpy- numpyè una libreria con un caso d'uso molto specifico e ha una diversa definizione "naturale" di ciò che la verità su un array è per Standard Python per contenitori. Ha senso ottimizzare per quel caso, nel modo che pathlibusa /per concatenare i percorsi invece di +- è non standard, ma ha senso nel contesto.
Gareth Latty,

9
Concordato. Il mio punto è solo che è importante ricordare che il numpy ha fatto la scelta di rompere la digitazione dell'anatra sia per il molto comune if xche per gli len(x)idiomi - e talvolta quella rottura può essere molto difficile da rilevare e debug.
Mike,

22
Non so, per me, se un metodo chiamato len (x) non restituisce la lunghezza dell'array a causa di ipotesi, il suo nome è mal progettato.
Dalton,

11
Questa domanda non ha nulla a che fare con gli array
intorpiditi

19
Sì, la domanda originale non riguardava le matrici di Numpy, ma quando si lavora con quelle e forse con argomenti dattiloscritti, questa domanda diventa molto rilevante.
peterhil,

223

Il modo migliore per verificare se un elenco è vuoto

Ad esempio, se superato quanto segue:

a = []

Come posso verificare se a è vuoto?

Risposta breve:

Posiziona l'elenco in un contesto booleano (ad esempio, con un'istruzione ifo while). Verificherà Falsese è vuoto e in caso Truecontrario. Per esempio:

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

PEP 8

PEP 8 , la guida ufficiale di stile Python per il codice Python nella libreria standard di Python, afferma:

Per le sequenze (stringhe, elenchi, tuple), usa il fatto che le sequenze vuote sono false.

Yes: if not seq:
     if seq:

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

Dovremmo aspettarci che il codice della libreria standard sia il più performante e corretto possibile. Ma perché è così, e perché abbiamo bisogno di questa guida?

Spiegazione

Vedo spesso codice come questo da programmatori esperti nuovi in ​​Python:

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

E gli utenti di lingue pigre possono essere tentati di farlo:

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

Questi sono corretti nelle rispettive altre lingue. E questo è anche semanticamente corretto in Python.

Ma lo consideriamo non-Pythonic perché Python supporta queste semantiche direttamente nell'interfaccia dell'oggetto elenco tramite coercizione booleana.

Dai documenti (e nota in particolare l'inclusione dell'elenco vuoto []):

Per impostazione predefinita, un oggetto è considerato vero a meno che la sua classe non definisca un __bool__()metodo che restituisce Falseo un __len__()metodo che restituisce zero, quando viene chiamato con l'oggetto. Ecco la maggior parte degli oggetti incorporati considerati falsi:

  • costanti definite come false: Nonee False.
  • zero di alcun tipo numerico: 0, 0.0, 0j, Decimal(0),Fraction(0, 1)
  • sequenze e collezioni vuoti: '', (), [], {}, set(),range(0)

E la documentazione del modello di dati:

object.__bool__(self)

Chiamato per implementare il test del valore di verità e l'operazione integrata bool(); dovrebbe tornare Falseo True. Quando questo metodo non è definito, __len__()viene chiamato, se è definito, e l'oggetto viene considerato vero se il suo risultato è diverso da zero. Se una classe non definisce né __len__()__bool__(), tutte le sue istanze sono considerate vere.

e

object.__len__(self)

Chiamato per implementare la funzione integrata len(). Dovrebbe restituire la lunghezza dell'oggetto, un numero intero> = 0. Inoltre, un oggetto che non definisce un __bool__()metodo e il cui __len__()metodo restituisce zero è considerato falso in un contesto booleano.

Quindi invece di questo:

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

o questo:

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

Fai questo:

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

Fare ciò che Pythonic di solito paga in termini di prestazioni:

Paga? (Si noti che meno tempo per eseguire un'operazione equivalente è meglio :)

>>> 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

Per la scala, ecco il costo per chiamare la funzione e costruire e restituire un elenco vuoto, che potresti sottrarre dai costi dei controlli di vuoto usati sopra:

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

Vediamo che il controllo della lunghezza con la funzione integrata lenrispetto 0 o il controllo su un elenco vuoto è molto meno performante rispetto all'utilizzo della sintassi incorporata del linguaggio come documentato.

Perché?

Per il len(a) == 0controllo:

Per prima cosa Python deve controllare i globi per vedere se lenè ombreggiato.

Quindi deve chiamare la funzione, caricare 0ed eseguire il confronto di uguaglianza in Python (anziché con 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

E per [] == []questo deve costruire un elenco non necessario e poi, di nuovo, eseguire l'operazione di confronto nella macchina virtuale di Python (al contrario di C)

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

Il modo "Pythonic" è un controllo molto più semplice e veloce poiché la lunghezza dell'elenco è memorizzata nella cache nell'intestazione dell'istanza dell'oggetto:

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

Prove dalla fonte C e documentazione

PyVarObject

Questa è un'estensione PyObjectche aggiunge il ob_sizecampo. Questo è usato solo per oggetti che hanno una nozione di lunghezza. Questo tipo non viene spesso visualizzato nell'API Python / C. Corrisponde ai campi definiti dall'espansione della PyObject_VAR_HEADmacro.

Dalla fonte c in 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

Risposta ai commenti:

Rilevo che ciò è vero anche per il caso non vuota se la sua abbastanza brutto as l=[]poi %timeit len(l) != 090,6 ± 8,3 ns ns, %timeit l != []55,6 ns ± 3,09, %timeit not not l38,5 ± 0,372 ns. Ma non c'è modo che nessuno possa godere not not lnonostante il triplo della velocità. Sembra ridicolo. Ma la velocità vince
Suppongo che il problema stia testando con il tempo poiché if l:è sufficiente ma sorprendentemente %timeit bool(l)produce 101 ns ± 2,64 ns. Interessante non c'è modo di costringere a booleare senza questa penalità. %timeit lè inutile poiché non si verificherebbe alcuna conversione.

La magia di IPython, %timeitqui non è del tutto inutile:

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)

Possiamo vedere che c'è un po 'di costo lineare per ogni ulteriore notqui. Vogliamo vedere i costi, ceteris paribus , cioè tutto il resto uguale - dove tutto il resto è minimizzato il più possibile:

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)

Ora diamo un'occhiata al caso di un elenco di disoccupati:

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)

Quello che possiamo vedere qui è che fa poca differenza se si passa da un controllo effettivo boolalla condizione o all'elenco stesso e, se non altro, dare l'elenco, così com'è, è più veloce.

Python è scritto in C; usa la sua logica a livello C. Qualunque cosa tu scriva in Python sarà più lenta. E probabilmente gli ordini di grandezza saranno più lenti a meno che tu non stia usando direttamente i meccanismi integrati in Python.


Rilevo che ciò è vero anche per il caso non vuota se la sua abbastanza brutto as l=[]poi %timeit len(l) != 090,6 ± 8,3 ns ns, %timeit l != []55,6 ns ± 3,09, %timeit not not l38,5 ± 0,372 ns. Ma non c'è modo che nessuno possa godere not not lnonostante il triplo della velocità. Sembra ridicolo. Ma la velocità vince
Gregory Morse,

Suppongo che il problema stia testando con timeit poiché if l:è sufficiente ma sorprendentemente %timeit bool(l)produce 101 ns ± 2,64 ns. Interessante non c'è modo di costringere a booleare senza questa penalità. %timeit lè inutile poiché non si verificherebbe alcuna conversione.
Gregory Morse,

139

Un elenco vuoto è di per sé considerato falso nel test di valori reali (vedere la documentazione di Python ):

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

@Daren Thomas

EDIT: un altro punto contro testare la lista vuota come False: che dire del polimorfismo? Non dovresti dipendere da un elenco che è un elenco. Dovrebbe semplicemente ciondolare come un'anatra - come hai intenzione di convincere la tua duckCollection a quackare '' False '' quando non ha elementi?

Il tuo duckCollection dovrebbe attuare __nonzero__o __len__in modo che il caso di: funzionerà senza problemi.


Strano come [] == Falsevaluterà False però
information_interchange

@information_interchange Se si desidera verificare esplicitamente la veridicità di un valore, utilizzare bool(). bool([]) == Falsevaluterà Truecome previsto.
agosto

103

La risposta (accettata) di Patrick è corretta:if not a: è il modo giusto di farlo. La risposta di Harley Holcombe è giusta nel fatto che questo è nella guida di stile PEP 8. Ma ciò che nessuna delle risposte spiega è perché è una buona idea seguire il linguaggio - anche se personalmente trovi che non è abbastanza esplicito o confuso per gli utenti di Ruby o altro.

Il codice Python e la comunità Python hanno un linguaggio molto forte. Seguire questi idiomi semplifica la lettura del codice per chiunque abbia esperienza in Python. E quando si violano questi idiomi, è un segnale forte.

È vero che if not a:non distingue elenchi vuoti da None, o 0 numerici, o tuple vuote, o tipi di raccolta vuoti creati dall'utente, o tipi di raccolta non proprio creati dall'utente vuoti, o array NumPy a singolo elemento che agisce come scalari con falso valori, ecc. E a volte è importante essere espliciti al riguardo. E in quel caso, sai di cosa vuoi essere esplicito, quindi puoi provare esattamente quello. Ad esempio, if not a and a is not None:significa "qualsiasi cosa falsa eccetto None", mentre if len(a) != 0:significa "solo sequenze vuote — e qualsiasi cosa oltre a una sequenza è un errore qui", e così via. Oltre a testare esattamente ciò che si desidera testare, questo segnala anche al lettore che questo test è importante.

Ma quando non hai nulla di esplicito, altro che if not a:fuorviare il lettore. Stai segnalando qualcosa di importante quando non lo è. (Si può anche essere rendere il codice meno flessibile, o più lento, o qualsiasi altra cosa, ma questo è tutto meno importante.) E se abitualmente indurre in errore il lettore come questo, poi, quando si fa necessità di fare una distinzione, sta andando a passare a causa inosservato hai "pianto lupo" in tutto il tuo codice.


78

Perché controllare affatto?

Nessuno sembra aver risposto mettendo in dubbio la necessità di testare l'elenco in primo luogo. Poiché non hai fornito alcun contesto aggiuntivo, posso immaginare che potresti non aver bisogno di fare questo controllo in primo luogo, ma non hai familiarità con l'elaborazione dell'elenco in Python.

Direi che il modo più pitone è non controllare affatto, ma piuttosto semplicemente elaborare l'elenco. In questo modo farà la cosa giusta, vuota o piena.

a = []

for item in a:
    <do something with item>

<rest of code>

Ciò ha il vantaggio di gestire qualsiasi contenuto di a , senza richiedere un controllo specifico per il vuoto. Se a è vuoto, il blocco dipendente non verrà eseguito e l'interprete passerà alla riga successiva.

Se in realtà è necessario controllare il vuoto dell'array, le altre risposte sono sufficienti.


3
Il fatto è che controllare se l'elenco è vuoto è abbastanza importante, almeno per me. Hai considerato se c'è qualche script all'interno <rest of code>che potrebbe utilizzare il risultato del forciclo? O utilizzare direttamente alcuni valori in a? In effetti, se lo script è progettato per essere eseguito con input strettamente controllati, il controllo potrebbe essere un po 'inutile. Ma nella maggior parte dei casi, l'input varia e avere un controllo è generalmente migliore.
Amarth Gûl,

Rispettosamente, no. Quello che ho considerato era qualcuno che non sapeva abbastanza su Python da sapere che "if <list>:" era la risposta corretta, chiedeva come controllare un elenco vuoto. Poi noto molte risposte che offrono opinioni diverse, ma nessuna sembra rispondere al bisogno originale. Questo è ciò che ho cercato di fare con la mia risposta: chiedi loro di esaminare la necessità prima di continuare. Credo di aver suggerito altrettanto nella mia risposta, esplicitamente.
MrWonderful,

@ AmarthGûl - Come si potrebbe ottenere i risultati dal ciclo for per l'interno di script <resto del code> da lavorare? In un elenco, forse? O forse un dict? In tal caso, si applica la stessa logica. Non capisco come l' input variabile possa avere alcun effetto all'interno di qualsiasi tipo di codice ragionevolmente progettato, in cui l'elaborazione di un elenco vuoto sarebbe una cattiva idea.
MrWonderful,

Un po 'vecchio ma se stavi solo controllando se l'elenco era vuoto, per un elenco non vuoto il tuo codice ripete ripetutamente il processo quando OP sta semplicemente cercando un'operazione di controllo. Immagina uno scenario peggiore per quel codice mentre n si avvicina all'infinito ....
DJK,

7
@DJK - No, penso che ti manchi ancora. Presumibilmente vuoi fare qualcosa con un elenco, se ne hai uno. Cosa faresti diversamente se fosse vuoto? Tornare presto? E se non fosse vuoto? elaborarlo? Il punto è, tuttavia, che probabilmente non hai bisogno di controllare un elenco vuoto, basta solo scorrere su di esso e fare tutto ciò che avresti fatto con gli elementi. Se non ci sono elementi, cadi. Se ci sono elementi, li elabori come è necessario. Il punto è NON usare l'esempio PER un controllo vuoto ma piuttosto NON controllare affatto, basta elaborare l'elenco.
MrWonderful,


40

Avevo scritto:

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

che è stato votato -1. Non sono sicuro se questo perché i lettori si sono opposti alla strategia o hanno pensato che la risposta non fosse utile come presentato. Farò finta che fosse quest'ultimo, dal momento che --- tutto ciò che conta come "pitonico" --- questa è la strategia corretta. A meno che non sia già stato escluso o non si sia pronti a gestire casi in cui a, ad esempio False, è necessario un test più restrittivo del semplice if not a:. Puoi usare qualcosa del genere:

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

il primo test è in risposta alla risposta di @ Mike, sopra. La terza riga potrebbe anche essere sostituita con:

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

se si desidera accettare solo istanze di tipi particolari (e relativi sottotipi) o con:

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

Puoi cavartela senza il controllo esplicito del tipo, ma solo se il contesto circostante ti assicura già che aè un valore dei tipi che sei pronto a gestire o se sei sicuro che i tipi che non sei pronto a gestire stanno andando per generare errori (ad es. a TypeErrorse si chiama lenun valore per il quale non è definito) che si è pronti a gestire. In generale, le convenzioni "pitoniche" sembrano andare in quest'ultima direzione. Strizzalo come un'anatra e lascia che alzi un DuckError se non sa come ciarlare. Devi ancora pensare a che tipo di ipotesi stai formulando, tuttavia, e se i casi che non sei preparato a gestire correttamente andranno davvero fuori posto nei posti giusti. Le matrici Numpy sono un buon esempio su cui basarsi ciecamentelen o il typecast booleano potrebbe non fare esattamente quello che ti aspetti.


3
È abbastanza raro che tu abbia un elenco esauriente di 6 tipi che vuoi accettare e non essere flessibile per nessun altro tipo. Quando hai bisogno di quel genere di cose, probabilmente vuoi una ABC. In questo caso, sarebbe probabilmente uno degli ABC stdlib, come collections.abc.Sizedo collections.abc.Sequence, ma potrebbe essere uno su cui scrivi tu stesso e register(list)su. Se in realtà hai un codice in cui è importante distinguere il vuoto dall'altra falsità e anche distinguere elenchi e tuple da qualsiasi altra sequenza, allora questo è corretto, ma non credo che tu abbia tale codice.
Abarnert,

13
Il motivo per cui alla gente non piace questo è perché nella maggior parte dei casi è del tutto inconsapevole. Python è un linguaggio tipicamente anatra, e questo livello di codifica difensiva lo ostacola attivamente. L'idea alla base del sistema di tipi di Python è che le cose dovrebbero funzionare fintanto che l'oggetto passa nelle funzioni nel modo in cui è necessario. Effettuando controlli espliciti sui tipi si sta costringendo il chiamante a utilizzare tipi specifici, andando contro lo stesso grido della lingua. Sebbene occasionalmente tali cose siano necessarie (escludendo che le stringhe vengano trattate come sequenze), tali casi sono rari e quasi sempre migliori come liste nere.
Gareth Latty,

1
Se vuoi davvero verificare che il valore sia esattamente []e non qualcosa di falso di un altro tipo, allora sicuramente if a == []:è richiesto, piuttosto che confondere con isinstance.
Remco Gerlich,

2
Però ci sono alcune coercizioni automatiche ==. Dalla parte superiore della mia testa, non riesco a identificarmi per []. [] == ()per esempio ritorna False. Ma per esempio frozenset()==set()ritorna True. Quindi vale la pena almeno riflettere su se un tipo indesiderato potrebbe essere costretto [](o viceversa) a farlo a == [].
dubiousjim,

@RemcoGerlich - isinstance () è ancora preferibile rispetto alla costruzione di un elenco vuoto da confrontare. Inoltre, come un altro ha sottolineato, l'operatore di uguaglianza può invocare la conversione implicita di alcuni tipi, il che può essere indesiderabile. Non c'è motivo di codificare mai "a == []" e quel codice sarebbe sicuramente contrassegnato come difetto in qualsiasi recensione di codice a cui ho partecipato. L'uso dello strumento appropriato fornito dalla lingua non dovrebbe essere considerato "confuso" , "ma piuttosto" buona tecnica di programmazione ".
MrWonderful,

29

Dalla documentazione sulla verifica del valore di verità:

Vengono considerati tutti i valori diversi da quelli elencati qui True

  • None
  • False
  • zero di alcun tipo numerico, ad esempio 0, 0.0, 0j.
  • qualsiasi sequenza vuota, per esempio '', (), [].
  • qualsiasi mappatura vuota, ad esempio {}.
  • istanze di classi definite dall'utente, se la classe definisce un metodo __bool__()o __len__(), quando quel metodo restituisce lo zero intero o il valore bool False.

Come si può vedere, l'elenco vuoto []è falso , quindi fare ciò che sarebbe fatto a un valore booleano sembra più efficiente:

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

@DJ_Stuffy_K affermano cosa nel test unitario, un elenco vuoto? Basta usare assert(not myList). Se vuoi anche affermare che l'oggetto è a list, puoi usarlo assertIsInstance().
Sнаđошƒаӽ,

24

Ecco alcuni modi per verificare se un elenco è vuoto:

a = [] #the list

1) Il modo piuttosto semplice di Pythonic:

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

In Python vengono visualizzati come contenitori vuoti come elenchi, tuple, set, dicts, variabili ecc False. Si potrebbe semplicemente considerare l'elenco come un predicato ( restituendo un valore booleano ). E un Truevalore indicherebbe che non è vuoto.

2) Un modo molto esplicito: usare il len()per trovare la lunghezza e verificare se è uguale a 0:

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

3) O confrontandolo con un elenco vuoto anonimo:

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

4) Un altro modo ancora sciocco da fare è usare exceptione iter():

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

20

Preferisco quanto segue:

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

37
Questo sarà più lento, poiché si crea un'istanza di un elenco vuoto aggiuntivo inutilmente.
Carl Meyer,

32
questo è meno leggibile di if not a:e si rompe più facilmente. Per favore, non farlo.
Devsnd

C'è un buon punto fatto in precedenza () == []è anche uguale a falso. Anche se mi piace il modo in cui questa implementazione legge le if not a:copertine di tutti i casi, se sicuramente ti aspetti un elenco, il tuo esempio dovrebbe essere sufficiente.
Una stella

19

Metodo 1 (preferito):

if not a : 
   print ("Empty") 

Metodo 2:

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

Metodo 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])

A volte è bene provare Noneseparatamente e per il vuoto in quanto si tratta di due stati diversi. Il codice sopra produce il seguente output:

list is None 
list is empty 
list has 3 elements

Anche se non vale nulla di Nonefalso. Quindi, se non vuoi separare il test per None-ness, non devi farlo.

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])

produce previsto

list is empty
list is empty
list has 3 elements

8

Sono state fornite molte risposte e molte sono abbastanza buone. Volevo solo aggiungere questo controllo

not a

passerà anche per Nonee altri tipi di strutture vuote. Se vuoi veramente controllare un elenco vuoto, puoi farlo:

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

È possibile che ciò generi un'eccezione, se anon è un elenco e anon ha alcun metodo __len__implementato. Consiglierei:if isinstance(obj, list): if len(obj) == 0: print '...'
Sven Krüger il

4
@ SvenKrüger no. L'operatore andè pigro in Python. Nulla dopo andverrà eseguito se la condizione precedente andè False.
ElmoVanKielmo,

7

potremmo usare un semplice se altrimenti:

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

5
-1 - Per evitare confusione, non usare parole riservate per i nomi delle variabili o potresti avere un comportamento sorprendente la prossima volta che provi a chiamare, ad esempio "list ()" ... qualcosa come "TypeError: l'oggetto 'list' è non richiamabile "o qualcosa del genere.
MrWonderful,

6

Se vuoi controllare se un elenco è vuoto:

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

Se si desidera verificare se tutti i valori nell'elenco sono vuoti. Tuttavia sarà Trueper un elenco vuoto:

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

Se si desidera utilizzare entrambi i casi insieme:

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

Ora puoi usare:

if empty_list(lst):
    # do your stuff.

1
all (bool (x) for x in l) è True per un elenco vuoto
gberger

5

Essendo ispirato dalla soluzione di @ dubiousjim, propongo di utilizzare un controllo generale aggiuntivo per capire se è qualcosa di iterabile

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

Nota: una stringa è considerata iterabile. - aggiungi and not isinstance(a,(str,unicode))se vuoi escludere la stringa vuota

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
overbroad; questo è solo chiedere se un elenco è vuoto, non se qualcosa è un iterabile vuoto.
pepery

1
Se non fossi contento if a:, sarebbe perché volevo un'eccezione se anon fosse una sorta di contenitore. (Essere un iterabile consente anche agli iteratori, che non possono essere utilmente testati per il vuoto.)
Davis Herring

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

un po 'più pratico:

a.pop() if a else None

e versione più sicura:

if a: a.pop() 

4

Da python3 in poi puoi usare

a == []

per verificare se l'elenco è vuoto

EDIT: funziona anche con python2.7.

Non sono sicuro del perché ci siano così tante risposte complicate. È abbastanza chiaro e semplice


1
per favore, dai maggiori spiegazioni su come funziona senza scrivere "if"?
Ganeshdeshmukh,

3
Questo non è un pitone né un esempio completo. Inoltre, crea un'istanza di un elenco vuoto ogni volta che viene rilevato. Non farlo
MrWonderful,

@MrWonderful non crea un'istanza di un elenco vuoto ogni volta. Verifica solo se l'elenco esistente aè vuoto o meno.
Tessaracter,

@MrWonderful Non capisco cosa lo rendepythonic
Tessaracter il

@ganeshdeshmukh se lo usi a==[], verrà stampato true sul terminale Python se a è vuoto. Altrimenti stamperà False. Puoi usarlo all'interno di una condizione if anche comeif(a==[])
Tessaracter

3

Puoi anche provare a usare bool () in questo modo

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

Adoro questo modo per controllare che la lista sia vuota o meno.

Molto utile e utile.


4
Per quelli (come me) che non lo sapevano, bool()converte una variabile Python in un valore booleano in modo da poter memorizzare la verità o la falsità di un valore senza dover usare un'istruzione if. Penso che sia meno leggibile del semplice utilizzo di un condizionale come la risposta accettata, ma sono sicuro che ci sono altri buoni casi d'uso per questo.
Galen Long,

Questo è utilizzabile in un'espressione ed è più conciso.
qneill,

3

Usa semplicemente is_empty () o crea una funzione come: -

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

Può essere utilizzato per qualsiasi struttura dati come un elenco, tuple, dizionario e molti altri. Con questi, puoi chiamarlo molte volte usando solo is_empty(any_structure).


3
Il nome is_emptysuggerisce che restituisce qualcosa. Ma se lo facesse, quel qualcosa sarebbe semplicemente bool(any_structure), che dovresti usare invece ( quando ne hai bisogno bool).
Davis Herring,

4
Perché vogliamo una variazione su boolche (anche) stampa i messaggi sullo standard output?
Davis Herring,

@DavisHerring Abbiamo sempre due opzioni per la prima volta è quella di stampare usando la funzione, l'altro sta usando la boolvariabile return . La scelta è tua. Scrivo entrambi in modo da poter scegliere tra di loro.
Vineet Jain,

3

Il modo semplice è verificare che la lunghezza sia uguale a zero.

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

1

Il valore di verità di un elenco vuoto è Falsementre per un elenco non vuoto lo è True.


1

Ciò che mi ha portato qui è un caso d'uso speciale: volevo davvero una funzione per dirmi se un elenco è vuoto o meno. Volevo evitare di scrivere la mia funzione o di usare un'espressione lambda qui (perché sembrava che dovesse essere abbastanza semplice):

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

E, naturalmente, esiste un modo molto naturale per farlo:

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

Naturalmente, non usare boolin if(cioè, if bool(L):) perché è implicito. Ma, per i casi in cui "non è vuoto" è esplicitamente necessario come funzione, boolè la scelta migliore.


1

Per verificare se un elenco è vuoto o meno, è possibile utilizzare due modi seguenti. Ma ricorda, dovremmo evitare il modo di verificare esplicitamente un tipo di sequenza (è un less pythonicmodo):

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".

Il secondo modo è more pythonicuno. Questo metodo è un modo implicito di controllo e molto più preferibile del precedente.

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"

Spero che sia di aiuto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.