Bagaimana saya memeriksa apakah daftar itu kosong?

3234

Misalnya, jika melewati berikut ini:

a = []

Bagaimana saya memeriksa untuk melihat apakah akosong?

sinar
sumber

Jawaban:

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

Menggunakan booleanness implisit dari yang kosong listcukup pythonic.

Patrick
sumber
1130
Bermain sebagai penasihat iblis. Saya tidak mengerti mengapa idiom ini dianggap pythonic. 'Eksplisit lebih baik daripada implisit', benar? Pemeriksaan ini tampaknya tidak terlalu eksplisit tentang apa yang diperiksa.
James McMahon
222
@JamesMcMahon - ini merupakan trade-off antara explicitness dan jenis fleksibilitas. umumnya, "menjadi eksplisit" berarti tidak melakukan hal-hal yang "ajaib". di sisi lain, "mengetik bebek" berarti bekerja dengan antarmuka yang lebih umum, daripada secara eksplisit memeriksa jenis. jadi sesuatu seperti if a == []memaksa jenis tertentu ( () == []adalah False). di sini, konsensus umum tampaknya bahwa pengetikan bebek menang (pada dasarnya, mengatakan bahwa itu __nonzero__adalah antarmuka untuk menguji kekosongan docs.python.org/reference/datamodel.html#object.__nonzero__ )
andrew cooke
38
Metode ini tidak bekerja pada array numpy .. jadi saya pikir jika len (a) == 0 lebih disukai baik dalam hal "mengetik bebek" dan implisit.
Mr.WorshipMe
10
Cara kanonik untuk mengetahui apakah array dalam C kosong adalah dengan mendereferensi elemen pertama dan melihat apakah itu nol, dengan asumsi array yang diakhiri nul. Kalau tidak, membandingkan panjangnya dengan nol sama sekali tidak efisien jika array berukuran besar. Juga, biasanya, Anda tidak akan mengalokasikan memori untuk array kosong (pointer tetap nol), jadi tidak masuk akal untuk mencoba mendapatkan panjangnya. Saya tidak mengatakan bahwa len (a) == 0 bukan cara yang baik untuk melakukannya, hanya saja tidak berteriak 'C' kepada saya ketika saya melihatnya.
sleblanc
6
@BrennenSprimont, Jika tidak diakhiri null, maka Anda sudah tahu panjangnya, apakah itu disimpan dalam variabel terpisah atau array Anda dibungkus dalam beberapa wadah yang melacak panjang. C ++, Java, C # memiliki wadah semacam itu dan mengimplementasikan beberapa metode "panjang" secara efisien. C tidak memiliki hal seperti itu , Anda harus memutar sendiri. Array C yang dialokasikan secara statis hanyalah penunjuk ke ruang memori yang dijamin memiliki cukup ruang untuk menyimpan jumlah data yang Anda minta. Tidak ada yang dibangun ke dalam C yang akan memberi tahu Anda seberapa banyak Anda telah mengisi ruang itu.
sleblanc
1160

Cara pythonic untuk melakukannya adalah dari panduan gaya PEP 8 (di mana Ya berarti "disarankan" dan Tidak berarti "tidak dianjurkan"):

Untuk urutan, (string, daftar, tupel), gunakan fakta bahwa urutan kosong salah.

Yes: if not seq:
     if seq:

No:  if len(seq):
     if not len(seq):
Harley Holcombe
sumber
49
Cara kedua tampaknya lebih baik jika Anda ingin memberi sinyal yang seqdiharapkan menjadi semacam objek daftar.
BallpointBen
5
@BallpointBen yang, kata pendukung Pythonism, harus tersirat dalam cara variabel dinamai, sebanyak mungkin
axolotl
9
@BallpointBen coba gunakan petunjuk tipe Python untuk memberi sinyal variabel apa yang seharusnya. Itu diperkenalkan di 3.5.
Boris
8
numpy memecahkan idiom ini ... seq = numpy.array ([1,2,3]) diikuti oleh jika tidak seq memunculkan eksepsi "ValueError: Nilai kebenaran sebuah array dengan lebih dari satu elemen bersifat ambigu. Gunakan a.any () atau a.all () "
Mr.WorshipMe
2
@ jeronimo: Saya percaya itu adalah peringatan khusus lxml.
Harley Holcombe
769

Saya lebih suka secara eksplisit:

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

Dengan cara ini 100% jelas itu liadalah urutan (daftar) dan kami ingin menguji ukurannya. Masalah saya dengan if not li: ...itu memberi kesan salah yaitu livariabel boolean.

Jabba
sumber
91
Memeriksa apakah panjang daftar sama dengan nol, dan bukan hanya memeriksa apakah daftar itu salah, jelek dan unpythonic. Siapa pun yang akrab dengan Python tidak akan berpikir liitu bool sama sekali, dan tidak peduli. Jika ini penting, Anda harus menambahkan komentar, bukan kode lagi.
Carl Smith
21
Ini tampaknya seperti tes tepat yang tidak perlu, yang sering lebih lambat dan selalu kurang terbaca IMHO. Alih-alih memeriksa ukuran sesuatu yang kosong, mengapa tidak memeriksa saja apakah itu kosong?
John B
34
Lagi pula, alasan ini buruk (dan bahwa melanggar idiom dalam bahasa dengan idiom kuat seperti Python secara umum buruk) adalah bahwa hal itu memberi sinyal kepada pembaca bahwa Anda secara khusus memeriksa panjang untuk beberapa alasan (misalnya, karena Anda ingin Noneatau 0untuk meningkatkan pengecualian daripada lewat). Jadi, ketika Anda melakukannya tanpa alasan, itu menyesatkan — dan itu juga berarti bahwa ketika kode Anda perlu membuat perbedaan, perbedaan itu tidak terlihat karena Anda telah "menangis serigala" di seluruh sumber.
abarnert
18
Saya pikir ini hanya perlu memperpanjang kode. Kalau tidak, mengapa tidak lebih "eksplisit" dengan if bool(len(li) == 0) is True:?
augurar
11
@ Jabba akan menjadi O (1) dalam banyak kasus (di mana Anda bekerja dengan tipe data bawaan), tetapi Anda tidak bisa mengandalkan itu. Anda mungkin bekerja dengan tipe data khusus yang tidak memiliki properti ini. Anda mungkin juga memutuskan untuk menambahkan tipe data khusus ini nanti, setelah Anda sudah menulis kode ini.
ralokt
325

Ini adalah hit google pertama untuk "python test blank array" dan pertanyaan serupa, ditambah orang lain tampaknya menggeneralisasi pertanyaan di luar daftar saja, jadi saya pikir saya akan menambahkan peringatan untuk jenis urutan yang berbeda yang banyak orang mungkin digunakan.

Metode lain tidak berfungsi untuk array NumPy

Anda harus berhati-hati dengan array NumPy, karena metode lain yang berfungsi baik untuk lists atau kontainer standar lainnya gagal untuk array NumPy. Saya menjelaskan mengapa di bawah ini, tetapi singkatnya, metode yang disukai adalah menggunakansize .

Cara "pythonic" tidak berfungsi: Bagian 1

Cara "pythonic" gagal dengan array NumPy karena NumPy mencoba untuk melemparkan array ke array bools, dan if xmencoba untuk mengevaluasi semua boolitu sekaligus untuk beberapa jenis nilai kebenaran agregat. Tetapi ini tidak masuk akal, jadi Anda mendapatkan 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()

Cara "pythonic" tidak berfungsi: Bagian 2

Tetapi setidaknya kasus di atas memberi tahu Anda bahwa itu gagal. Jika Anda memiliki array NumPy dengan tepat satu elemen, ifpernyataan itu akan "berfungsi", dalam arti bahwa Anda tidak mendapatkan kesalahan. Namun, jika satu elemen tersebut kebetulan 0( 0.0atau False, ...), ifpernyataan tersebut akan menghasilkan False:

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

Tetapi jelas xada dan tidak kosong! Hasil ini bukan yang Anda inginkan.

Menggunakan len dapat memberikan hasil yang tidak terduga

Sebagai contoh,

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

mengembalikan 1, meskipun array memiliki elemen nol.

Cara numpythonic

Seperti dijelaskan dalam FAQ SciPy , metode yang benar dalam semua kasus di mana Anda tahu Anda memiliki array NumPy adalah menggunakan 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

Jika Anda tidak yakin apakah itu mungkin listarray, NumPy, atau yang lain, Anda bisa menggabungkan pendekatan ini dengan jawaban yang diberikan @dubiousjim untuk memastikan tes yang tepat digunakan untuk setiap jenis. Tidak terlalu "pythonic", tetapi ternyata NumPy sengaja mematahkan pythonicity setidaknya dalam pengertian ini.

Jika Anda perlu melakukan lebih dari sekadar memeriksa apakah input kosong, dan Anda menggunakan fitur NumPy lainnya seperti operasi pengindeksan atau matematika, mungkin lebih efisien (dan tentu saja lebih umum) untuk memaksa input menjadi array NumPy. Ada beberapa fungsi bagus untuk melakukan ini dengan cepat - yang paling penting numpy.asarray. Ini mengambil input Anda, tidak melakukan apa-apa jika sudah menjadi array, atau membungkus input Anda ke dalam array jika itu adalah daftar, tuple, dll., Dan secara opsional mengubahnya ke yang Anda pilih dtype. Jadi itu sangat cepat kapanpun bisa, dan itu memastikan bahwa Anda hanya bisa berasumsi input adalah array NumPy. Kami biasanya bahkan hanya menggunakan nama yang sama, karena konversi ke array tidak akan membuatnya kembali di luar cakupan saat ini :

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

Ini akan membuat x.sizepemeriksaan berfungsi dalam semua kasus yang saya lihat di halaman ini.

Mike
sumber
62
Perlu dicatat bahwa ini bukan cacat dalam Python, melainkan pemutusan yang disengaja oleh numpy- numpyadalah pustaka dengan kasus penggunaan yang sangat spesifik, dan memiliki definisi 'alami' yang berbeda tentang apa kebenaran pada array bagi Standar python untuk kontainer. Masuk akal untuk mengoptimalkan untuk kasus itu, dengan cara yang pathlibdigunakan /untuk menggabungkan jalur bukannya +- itu tidak standar, tetapi masuk akal dalam konteks.
Gareth Latty
9
Sepakat. Maksud saya adalah bahwa penting untuk diingat bahwa numpy telah membuat pilihan untuk menghentikan pengetikan bebek untuk idiom yang sangat umum if xdan len(x)- dan kadang-kadang kerusakan itu sangat sulit untuk dideteksi dan didebug.
Mike
22
Saya tidak tahu, bagi saya, jika metode yang disebut len ​​(x) tidak mengembalikan panjang array karena asumsi, namanya dirancang buruk.
Dalton
11
Pertanyaan ini tidak ada hubungannya dengan array numpy
pppery
19
@ppperry Ya, pertanyaan asli bukan tentang array Numpy, tetapi ketika bekerja dengan argumen-argumen yang diketik dan mungkin bebek, pertanyaan ini menjadi sangat relevan.
peterhil
223

Cara terbaik untuk memeriksa apakah daftar kosong

Misalnya, jika melewati berikut ini:

a = []

Bagaimana saya memeriksa untuk melihat apakah a kosong?

Jawaban singkat:

Tempatkan daftar dalam konteks boolean (misalnya, dengan ifatau whilepernyataan). Ini akan menguji Falseapakah itu kosong, dan Truesebaliknya. Sebagai contoh:

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

PEP 8

PEP 8 , panduan gaya Python resmi untuk kode Python di pustaka standar Python, menegaskan:

Untuk urutan, (string, daftar, tupel), gunakan fakta bahwa urutan kosong salah.

Yes: if not seq:
     if seq:

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

Kita harus berharap bahwa kode pustaka standar harus sebagai pemain dan setepat mungkin. Tetapi mengapa demikian, dan mengapa kita membutuhkan bimbingan ini?

Penjelasan

Saya sering melihat kode seperti ini dari programmer berpengalaman yang baru menggunakan Python:

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

Dan pengguna bahasa yang malas mungkin tergoda untuk melakukan ini:

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

Ini benar dalam bahasa masing-masing lainnya. Dan ini bahkan semantik benar dalam Python.

Tapi kami menganggapnya tidak-Pythonic karena Python mendukung semantik ini secara langsung di antarmuka daftar objek melalui paksaan boolean.

Dari dokumen (dan perhatikan secara khusus penyertaan daftar kosong, []):

Secara default, objek dianggap benar kecuali kelasnya mendefinisikan __bool__()metode yang mengembalikan Falseatau __len__()metode yang mengembalikan nol, ketika dipanggil dengan objek. Berikut ini sebagian besar objek bawaan yang dianggap salah:

  • konstanta didefinisikan sebagai salah: Nonedan False.
  • nol dari setiap tipe numerik: 0, 0.0, 0j, Decimal(0),Fraction(0, 1)
  • urutan kosong dan koleksi: '', (), [], {}, set(),range(0)

Dan dokumentasi model data:

object.__bool__(self)

Dipanggil untuk menerapkan pengujian nilai kebenaran dan operasi internal bool(); harus kembali Falseatau True. Ketika metode ini tidak didefinisikan, __len__()dipanggil, jika didefinisikan, dan objek dianggap benar jika hasilnya nol. Jika suatu kelas tidak mendefinisikan __len__() juga __bool__(), semua instance nya dianggap benar.

dan

object.__len__(self)

Dipanggil untuk mengimplementasikan fungsi bawaan len(). Harus mengembalikan panjang objek, bilangan bulat> = 0. Juga, objek yang tidak mendefinisikan __bool__()metode dan __len__()metode yang mengembalikan nol dianggap salah dalam konteks Boolean.

Jadi alih-alih ini:

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

atau ini:

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

Melakukan hal ini:

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

Melakukan apa yang Pythonic biasanya terbayar dalam kinerja:

Apakah itu membuahkan hasil? (Perhatikan bahwa lebih sedikit waktu untuk melakukan operasi yang setara lebih baik :)

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

Untuk skala, inilah biaya memanggil fungsi dan membangun dan mengembalikan daftar kosong, yang dapat Anda kurangi dari biaya pemeriksaan kekosongan yang digunakan di atas:

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

Kami melihat bahwa baik pengecekan untuk panjang dengan fungsi builtin lendibandingkan dengan 0 atau pemeriksaan terhadap daftar kosong adalah banyak lebih performant daripada menggunakan sintaks builtin bahasa yang didokumentasikan.

Mengapa?

Untuk len(a) == 0 cek:

Python pertama harus memeriksa global untuk melihat apakah len dibayangi.

Maka itu harus memanggil fungsi, memuat 0, dan melakukan perbandingan kesetaraan dengan Python (bukan dengan 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

Dan untuk [] == []itu harus membangun daftar yang tidak perlu dan kemudian, sekali lagi, lakukan operasi perbandingan di mesin virtual Python (sebagai lawan dari C)

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

Cara "Pythonic" adalah pemeriksaan yang jauh lebih sederhana dan lebih cepat karena panjang daftar di-cache di header instance objek:

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

Bukti dari sumber C dan dokumentasi

PyVarObject

Ini adalah ekstensi PyObjectyang menambahkan ob_sizebidang. Ini hanya digunakan untuk objek yang memiliki gagasan panjang. Jenis ini tidak sering muncul di API Python / C. Ini sesuai dengan bidang yang ditentukan oleh ekspansi PyObject_VAR_HEADmakro.

Dari sumber c di Sertakan / 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

Tanggapan terhadap komentar:

Saya akan menunjukkan bahwa ini juga berlaku untuk kasus non-kosong meskipun cukup jelek sebagai dengan l=[]kemudian %timeit len(l) != 090,6 ns ± 8,3 ns, %timeit l != []55,6 ns ± 3,09, %timeit not not l38,5 ns ± 0,372. Tapi tidak mungkin ada orang yang bisa menikmati not not lmeskipun kecepatannya tiga kali lipat. Itu terlihat konyol. Tetapi kecepatan menang
saya kira masalahnya adalah pengujian dengan timeit karena hanya if l:cukup tetapi secara mengejutkan %timeit bool(l)menghasilkan 101 ns ± 2.64 ns. Menarik tidak ada cara untuk memaksa untuk bool tanpa penalti ini. %timeit ltidak berguna karena tidak ada konversi yang akan terjadi.

IPython magic,, %timeittidak sepenuhnya tidak berguna di sini:

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)

Kita dapat melihat ada sedikit biaya linear untuk setiap tambahan di notsini. Kami ingin melihat biaya, ceteris paribus , yaitu, semuanya sama - di mana semuanya diminimalisasi sejauh mungkin:

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)

Sekarang mari kita lihat case untuk daftar pengangguran:

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)

Apa yang dapat kita lihat di sini adalah tidak ada bedanya apakah Anda memasukkan data aktual bool ke cek kondisi atau daftar itu sendiri, dan jika ada, memberikan daftar, seperti, lebih cepat.

Python ditulis dalam C; ia menggunakan logikanya pada level C. Apa pun yang Anda tulis dengan Python akan lebih lambat. Dan itu kemungkinan akan menjadi urutan besarnya lebih lambat kecuali jika Anda menggunakan mekanisme yang dibangun ke Python secara langsung.

Aaron Hall
sumber
Saya akan menunjukkan bahwa ini juga berlaku untuk kasus non-kosong meskipun cukup jelek sebagai dengan l=[]kemudian %timeit len(l) != 090,6 ns ± 8,3 ns, %timeit l != []55,6 ns ± 3,09, %timeit not not l38,5 ns ± 0,372. Tapi tidak mungkin ada orang yang bisa menikmati not not lmeskipun kecepatannya tiga kali lipat. Itu terlihat konyol. Tetapi kecepatan menang
Gregory Morse
Saya kira masalahnya adalah pengujian dengan timeit karena if l:sudah cukup tetapi secara mengejutkan %timeit bool(l)menghasilkan 101 ns ± 2.64 ns. Menarik tidak ada cara untuk memaksa untuk bool tanpa penalti ini. %timeit ltidak berguna karena tidak ada konversi yang akan terjadi.
Gregory Morse
139

Daftar kosong sendiri dianggap salah dalam pengujian nilai sebenarnya (lihat dokumentasi python ):

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

@ Daren Thomas

EDIT: Poin lain terhadap pengujian daftar kosong sebagai False: Bagaimana dengan polimorfisme? Anda tidak harus bergantung pada daftar menjadi daftar. Seharusnya dukun seperti bebek - bagaimana Anda akan mendapatkan duckCollection Anda untuk dukun '' Salah '' ketika tidak memiliki elemen?

DuckCollection Anda harus menerapkan __nonzero__atau __len__lebih jika a: akan bekerja tanpa masalah.

Peter Hoffmann
sumber
Aneh bagaimana [] == Falseakan mengevaluasi ke False meskipun
information_interchange
@information_interchange Jika Anda ingin secara eksplisit memeriksa kebenaran suatu nilai, gunakan bool(). bool([]) == Falseakan mengevaluasi Trueseperti yang diharapkan.
augurar
103

Jawaban Patrick (diterima) benar: if not a:adalah cara yang tepat untuk melakukannya. Jawaban Harley Holcombe benar bahwa ini ada dalam panduan gaya PEP 8. Tetapi apa yang tidak dijelaskan oleh jawaban adalah mengapa itu ide yang baik untuk mengikuti idiom itu — bahkan jika Anda secara pribadi menemukan itu tidak cukup eksplisit atau membingungkan bagi pengguna Ruby atau apa pun.

Kode python, dan komunitas Python, memiliki idiom yang sangat kuat. Mengikuti idiom-idiom itu membuat kode Anda lebih mudah dibaca untuk siapa pun yang berpengalaman dengan Python. Dan ketika Anda melanggar idiom-idiom itu, itu sinyal yang kuat.

Memang benar bahwa if not a:tidak membedakan daftar kosong dari None, atau angka 0, atau tuple kosong, atau tipe koleksi yang dibuat pengguna kosong, atau tipe-tipe koleksi tidak-cukup-kosong yang dibuat pengguna, atau array NumPy elemen tunggal yang bertindak sebagai skalar dengan falsey nilai-nilai, dll. Dan kadang-kadang penting untuk eksplisit tentang itu. Dan dalam hal ini, Anda tahu apa yang ingin Anda jelaskan, sehingga Anda bisa menguji persisnya. Misalnya, if not a and a is not None:berarti "apa pun yang palsu kecuali Tidak Ada", sedangkan if len(a) != 0:berarti "hanya urutan kosong — dan apa pun selain urutan adalah kesalahan di sini", dan seterusnya. Selain menguji dengan tepat apa yang ingin Anda uji, ini juga memberi sinyal kepada pembaca bahwa tes ini penting.

Tetapi ketika Anda tidak memiliki sesuatu untuk menjadi eksplisit tentang, apa pun selain if not a:menyesatkan pembaca. Anda memberi sinyal sesuatu yang sama pentingnya ketika tidak. (Anda juga dapat membuat kode kurang fleksibel, atau lebih lambat, atau apa pun, tapi itu semua kurang penting.) Dan jika Anda terbiasa menyesatkan pembaca seperti ini, maka ketika Anda lakukan perlu membuat sebuah perbedaan, itu akan lulus karena tanpa disadari Anda sudah "menangis serigala" di seluruh kode Anda.

abarnert
sumber
78

Kenapa periksa sama sekali?

Tampaknya tidak ada yang menjawab pertanyaan Anda tentang kebutuhan untuk menguji daftar. Karena Anda tidak memberikan konteks tambahan, saya dapat membayangkan bahwa Anda mungkin tidak perlu melakukan pemeriksaan ini di tempat pertama, tetapi tidak terbiasa dengan pemrosesan daftar dengan Python.

Saya berpendapat bahwa cara paling pythonic adalah untuk tidak memeriksa sama sekali, tetapi lebih dari sekadar memproses daftar. Dengan begitu ia akan melakukan hal yang benar apakah kosong atau penuh.

a = []

for item in a:
    <do something with item>

<rest of code>

Ini memiliki manfaat penanganan setiap isi sebuah , sementara tidak memerlukan pemeriksaan khusus untuk kekosongan. Jika a kosong, blok dependen tidak akan mengeksekusi dan penerjemah akan jatuh ke baris berikutnya.

Jika Anda benar-benar perlu memeriksa array untuk kekosongan, jawaban lain sudah cukup.

MrWificent
sumber
3
Masalahnya, periksa apakah daftarnya kosong cukup penting, setidaknya untuk saya. Sudahkah Anda mempertimbangkan jika ada beberapa skrip di dalam <rest of code>yang mungkin menggunakan hasil dari forloop? Atau langsung menggunakan beberapa nilai a? Memang, jika skrip dirancang untuk dijalankan dengan input yang dikontrol ketat, pemeriksaan mungkin sedikit tidak perlu. Tetapi dalam kebanyakan kasus, input bervariasi, dan periksa biasanya lebih baik.
Amarth Gûl
Dengan hormat, tidak. Apa yang saya pertimbangkan adalah seseorang yang tidak cukup tahu tentang Python untuk mengetahui bahwa "jika <list>:" adalah jawaban yang benar, bertanya bagaimana cara memeriksa daftar kosong. Kemudian saya melihat BANYAK jawaban yang menawarkan pendapat yang berbeda, tetapi sepertinya tidak ada yang menjawab kebutuhan awal. Itulah yang saya coba lakukan dengan jawaban saya — mintalah mereka memeriksa kebutuhan sebelum melanjutkan. Saya yakin saya menyarankan sebanyak mungkin dalam jawaban saya, secara eksplisit.
MrWerlang
@ AmarthGûl - Bagaimana mungkin seseorang mendapatkan hasil dari for loop ke skrip di dalam <sisa kode> yang akan diproses? Dalam daftar, mungkin? Atau mungkin dict? Jika demikian, logika yang sama berlaku. Saya tidak mengerti bagaimana input variabel dapat memiliki efek dalam segala jenis kode yang dirancang secara wajar, di mana memproses daftar kosong akan menjadi ide yang buruk.
MrWerlang
Agak lama tetapi jika Anda hanya memeriksa apakah daftar itu kosong, untuk daftar yang tidak kosong kode Anda mengulangi proses berulang ketika OP hanya mencari operasi pemeriksaan. Bayangkan saja skenario kasus yang lebih buruk untuk kode itu ketika n mendekati tak terhingga ....
DJK
7
@ DJJ - Tidak, saya pikir Anda masih melewatkannya. Agaknya Anda ingin MELAKUKAN sesuatu dengan daftar, jika ada. Apa yang akan Anda lakukan secara berbeda jika kosong? Kembali lebih awal? Bagaimana jika tidak kosong? memprosesnya? Intinya adalah, masih, bahwa Anda mungkin tidak perlu memeriksa daftar kosong, hanya beralih dan lakukan apa pun yang akan Anda lakukan dengan elemen. Jika tidak ada elemen, Anda gagal. Jika ada elemen, Anda memprosesnya sesuai kebutuhan. Intinya adalah BUKAN untuk menggunakan contoh UNTUK cek-kosong tetapi bukan untuk memeriksa sama sekali, hanya memproses daftar.
MrWificent
40

Saya telah menulis:

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

yang terpilih sebagai -1. Saya tidak yakin apakah itu karena pembaca keberatan dengan strategi atau berpikir jawabannya tidak membantu seperti yang disajikan. Saya akan berpura-pura itu yang terakhir, karena --- apapun yang dianggap sebagai "pythonic" --- ini adalah strategi yang tepat. Kecuali Anda sudah mengesampingkan, atau siap untuk menangani kasus-kasus di mana a, misalnya False, Anda memerlukan tes yang lebih ketat daripada hanya if not a:. Anda dapat menggunakan sesuatu seperti ini:

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

tes pertama adalah jawaban atas jawaban @ Mike di atas. Baris ketiga juga bisa diganti dengan:

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

jika Anda hanya ingin menerima contoh jenis tertentu (dan subtipe mereka), atau dengan:

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

Anda bisa pergi tanpa pemeriksaan tipe eksplisit, tetapi hanya jika konteks sekitarnya sudah meyakinkan Anda bahwa itu aadalah nilai dari tipe yang siap Anda tangani, atau jika Anda yakin bahwa tipe yang tidak siap Anda tangani akan berjalan untuk meningkatkan kesalahan (misalnya, TypeErrorjika Anda memanggil lennilai yang tidak ditentukan) yang siap Anda tangani. Secara umum, konvensi "pythonic" tampaknya berjalan sejauh ini. Peras itu seperti bebek dan biarkan ia mengangkat DuckError jika tidak tahu bagaimana cara dukun. Anda masih harus berpikir tentang asumsi tipe apa yang Anda buat, dan apakah kasus-kasus yang Anda tidak siap tangani dengan benar akan salah di tempat yang tepat. Array Numpy adalah contoh yang baik di mana hanya mengandalkan secara membabi butalen atau typecast boolean mungkin tidak melakukan apa yang Anda harapkan.

dubiousjim
sumber
3
Sangat jarang bahwa Anda akan memiliki daftar lengkap dari 6 jenis yang ingin Anda terima dan tidak fleksibel untuk jenis lainnya. Ketika Anda membutuhkan hal semacam itu, Anda mungkin menginginkan ABC. Dalam hal ini, mungkin itu akan menjadi salah satu ABC stdlib, suka collections.abc.Sizedatau collections.abc.Sequence, tapi mungkin itu yang Anda tulis sendiri dan register(list)terus. Jika Anda benar-benar memiliki kode di mana penting untuk membedakan kosong dari falsey lain, dan juga untuk membedakan daftar dan tupel dari urutan lainnya, maka ini benar — tetapi saya tidak percaya Anda memiliki kode seperti itu.
abarnert
13
Alasan orang tidak suka ini adalah karena itu sepenuhnya tidak sehat dalam banyak kasus. Python adalah bahasa yang diketik bebek, dan tingkat pengkodean defensif ini secara aktif menghalangi hal itu. Gagasan di balik sistem tipe Python adalah bahwa segala sesuatu harus bekerja selama objek melewati fungsi dalam cara yang diperlukan. Dengan melakukan pemeriksaan jenis eksplisit, Anda memaksa penelepon untuk menggunakan jenis tertentu, bertentangan dengan butir bahasa. Sementara kadang-kadang hal-hal seperti itu diperlukan (tidak termasuk string dari diperlakukan sebagai urutan), kasus-kasus seperti itu jarang dan hampir selalu terbaik sebagai daftar hitam.
Gareth Latty
1
Jika Anda benar-benar ingin memeriksa bahwa nilainya tepat []dan bukan sesuatu yang salah dari tipe lain, maka pasti diperlukan if a == []:, daripada mucking tentang dengan isinstance.
RemcoGerlich
2
Namun ada beberapa paksaan otomatis ==. Dari atas kepala saya, saya tidak dapat mengidentifikasi untuk []. [] == ()misalnya pengembalian False. Tetapi misalnya frozenset()==set()kembali True. Jadi ada baiknya setidaknya memikirkan apakah beberapa tipe yang tidak diinginkan mungkin dipaksa [](atau sebaliknya) saat melakukannya a == [].
dubiousjim
@RemcoGerlich - isinstance () masih lebih disukai daripada membangun daftar kosong untuk dibandingkan. Juga, seperti yang ditunjukkan lain, operator kesetaraan dapat melakukan konversi implisit dari beberapa jenis, yang mungkin tidak diinginkan. Tidak ada alasan untuk pernah kode "a == []" dan kode itu pasti akan ditandai sebagai cacat dalam ulasan kode apa pun yang saya ikuti. Menggunakan alat yang sesuai seperti yang disediakan oleh bahasa tidak boleh dianggap "mucking about , "melainkan" teknik pemrograman yang baik. "
MrWificent
29

Dari dokumentasi pengujian nilai kebenaran:

Semua nilai selain dari yang tercantum di sini dipertimbangkan True

  • None
  • False
  • nol dari setiap tipe numerik, misalnya, 0, 0.0, 0j.
  • setiap urutan kosong, misalnya, '', (), [].
  • pemetaan kosong, misalnya {},.
  • contoh kelas yang ditentukan pengguna, jika kelas mendefinisikan metode __bool__()atau __len__(), ketika metode itu mengembalikan nilai integer nol atau bool False.

Seperti yang dapat dilihat, daftar kosong []adalah palsu , jadi melakukan apa yang akan dilakukan pada nilai boolean terdengar paling efisien:

if not a:
    print('"a" is empty!')
Sнаđошƒаӽ
sumber
@DJ_Stuffy_K menyatakan apa dalam pengujian unit, daftar kosong? Gunakan saja assert(not myList). Jika Anda juga ingin menegaskan objek adalah list, Anda dapat menggunakan assertIsInstance().
Sнаđошƒаӽ
24

Berikut adalah beberapa cara Anda dapat memeriksa apakah daftar kosong:

a = [] #the list

1) Cara pythonic yang cukup sederhana:

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

Dalam Python, wadah kosong seperti daftar, tupel, set, dicts, variabel dll dilihat sebagai False. Orang bisa dengan mudah memperlakukan daftar sebagai predikat ( mengembalikan nilai Boolean ). Dan Truenilai akan menunjukkan bahwa itu tidak kosong.

2) Cara yang lebih eksplisit: gunakan len()untuk menemukan panjang dan periksa apakah sama dengan 0:

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

3) Atau membandingkannya dengan daftar kosong anonim:

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

4) Cara lain yang konyol untuk dilakukan adalah menggunakan exceptiondan iter():

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

Saya lebih suka yang berikut ini:

if a == []:
   print "The list is empty."
verix
sumber
37
Ini akan menjadi lebih lambat, karena Anda membuat instantiate daftar kosong tambahan tidak perlu.
Carl Meyer
32
ini lebih mudah dibaca daripada if not a:dan lebih mudah rusak. Tolong jangan lakukan itu.
devsnd
Ada poin bagus yang dibuat sebelumnya () == []juga sama dengan false. Meskipun saya suka bagaimana implementasi ini membaca if not a:sampul semua kasus, jika Anda benar-benar mengharapkan daftar maka contoh Anda harus cukup.
Bintang
19

Metode 1 (Lebih disukai):

if not a : 
   print ("Empty") 

Metode 2:

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

Metode 3:

if a == [] :
  print ("Empty")
Vikrant
sumber
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])

Kadang-kadang baik untuk menguji Nonedan untuk kekosongan secara terpisah karena mereka adalah dua keadaan yang berbeda. Kode di atas menghasilkan output berikut:

list is None 
list is empty 
list has 3 elements

Meskipun tidak ada nilainya yang Nonepalsu. Jadi jika Anda tidak ingin memisahkan tes untuk None-ness, Anda tidak perlu melakukan itu.

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

menghasilkan yang diharapkan

list is empty
list is empty
list has 3 elements
Tagar
sumber
8

Banyak jawaban telah diberikan, dan banyak dari mereka cukup bagus. Saya hanya ingin menambahkan cek itu

not a

juga akan lulus Nonedan jenis struktur kosong lainnya. Jika Anda benar-benar ingin memeriksa daftar kosong, Anda dapat melakukan ini:

if isinstance(a, list) and len(a)==0:
    print("Received an empty list")
HackerBoss
sumber
Mungkin ini melempar pengecualian, jika abukan daftar dan atidak ada metode yang __len__diterapkan. Saya akan merekomendasikan:if isinstance(obj, list): if len(obj) == 0: print '...'
Sven Krüger
4
@ SvenKrüger nggak. Operator andmalas dengan Python. Tidak ada andyang akan dieksekusi jika kondisi sebelumnya andsalah.
ElmoVanKielmo
7

kita bisa menggunakan yang sederhana jika lain:

item_list=[]
if len(item_list) == 0:
    print("list is empty")
else:
    print("list is not empty")
l. zhang
sumber
5
-1 - Untuk menghindari kebingungan, jangan gunakan kata-kata yang dicadangkan untuk nama variabel atau Anda mungkin mendapatkan perilaku mengejutkan saat Anda mencoba menelepon, misalnya "list ()" ... sesuatu seperti "TypeError: objek 'list' adalah tidak dapat dipanggil "atau semacamnya.
MrWificent
6

Jika Anda ingin memeriksa apakah daftar kosong:

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

Jika Anda ingin memeriksa apakah semua nilai dalam daftar kosong. Namun itu Trueuntuk daftar kosong:

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

Jika Anda ingin menggunakan kedua kasus bersama-sama:

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

Sekarang Anda dapat menggunakan:

if empty_list(lst):
    # do your stuff.
Rahul
sumber
1
semua (bool (x) untuk x in l) Benar untuk daftar kosong
gberger
5

Terinspirasi oleh solusi @ dubiousjim, saya mengusulkan untuk menggunakan pemeriksaan umum tambahan apakah itu sesuatu yang dapat diubah

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

Catatan: string dianggap iterable. - tambahkan and not isinstance(a,(str,unicode))jika Anda ingin string kosong dikecualikan

Uji:

>>> 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
AndreyS Scherbakov
sumber
1
Overbroad; ini hanya menanyakan apakah daftar itu kosong, bukan apakah ada sesuatu yang kosong.
pppery
1
Jika saya tidak senang if a:, itu karena saya ingin pengecualian jika abukan semacam wadah. (Menjadi pengulangan juga memungkinkan pengulangan, yang tidak bisa diuji dengan sia-sia.)
Davis Herring
5
print('not empty' if a else 'empty')

sedikit lebih praktis:

a.pop() if a else None

dan versi shertest:

if a: a.pop() 
Andrey Suglobov
sumber
4

Dari python3 dan seterusnya, Anda dapat menggunakan

a == []

untuk memeriksa apakah daftar itu kosong

EDIT: Ini juga berfungsi dengan python2.7 ..

Saya tidak yakin mengapa ada begitu banyak jawaban yang rumit. Ini cukup jelas dan mudah

Tessaracter
sumber
1
tolong beri penjelasan lebih lanjut tentang cara kerjanya tanpa menulis "jika"?
ganeshdeshmukh
3
Ini bukan pythonic atau contoh lengkap. Juga, Ini instantiates daftar kosong setiap kali ditemukan. Jangan lakukan ini.
MrWificent
@ MrWificent itu tidak membuat daftar kosong setiap waktu. Itu hanya memverifikasi apakah daftar yang aada kosong atau tidak.
Tessaracter
@Mrantis, saya tidak mengerti apa yang membuatnyapythonic
Tessaracter
@ganeshdeshmukh jika Anda menggunakannya a==[]akan mencetak true pada terminal python jika a kosong. Jika tidak maka akan mencetak False. Anda dapat menggunakan ini di dalam kondisi if juga sebagaiif(a==[])
Tessaracter
3

Anda bahkan dapat mencoba menggunakan bool () seperti ini

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

Saya suka cara ini karena daftar periksa kosong atau tidak.

Sangat berguna dan bermanfaat.

Sunil Lulla
sumber
4
Bagi mereka (seperti saya) yang tidak tahu, bool()ubah variabel Python menjadi boolean sehingga Anda bisa menyimpan kebenaran atau kepalsuan dari suatu nilai tanpa harus menggunakan pernyataan if. Saya pikir itu kurang mudah dibaca daripada hanya menggunakan kondisional seperti jawaban yang diterima, tapi saya yakin ada beberapa kasus penggunaan yang baik untuk itu.
Galen Long
Ini dapat digunakan dalam ekspresi dan lebih singkat.
qneill
3

Cukup gunakan is_empty () atau buat fungsi seperti: -

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

Ini dapat digunakan untuk struktur data apa saja seperti daftar, tupel, kamus, dan banyak lagi. Dengan ini, Anda dapat menyebutnya berkali-kali hanya dengan menggunakan is_empty(any_structure).

Vineet Jain
sumber
3
Namanya is_emptymenunjukkan bahwa ia mengembalikan sesuatu. Tetapi jika itu terjadi, sesuatu itu akan terjadi bool(any_structure), yang harus Anda gunakan sebagai gantinya ( ketika Anda membutuhkannya bool).
Davis Herring
4
Mengapa kita ingin variasi pada boolitu (juga) mencetak pesan ke output standar?
Davis Herring
@ Davidviser Kami selalu memiliki dua pilihan pertama adalah mencetak menggunakan fungsi lainnya menggunakan boolvariabel kembali . Pilihan ada pada Anda. Saya menulis keduanya sehingga Anda dapat memilih di antara mereka.
Vineet Jain
3

Cara sederhana adalah memeriksa panjangnya sama dengan nol.

if len(a) == 0:
    print("a is empty")
Ashiq Imran
sumber
1

Nilai kebenaran dari daftar kosong adalah Falsesedangkan untuk daftar tidak kosong itu True.

MiloMinderbinder
sumber
1

Yang membawa saya ke sini adalah kasus penggunaan khusus: Saya sebenarnya ingin fungsi memberi tahu saya apakah daftar itu kosong atau tidak. Saya ingin menghindari menulis fungsi saya sendiri atau menggunakan ekspresi lambda di sini (karena sepertinya itu harus cukup sederhana):

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

Dan, tentu saja, ada cara yang sangat alami untuk melakukannya:

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

Tentu saja, jangan tidak menggunakan booldi if(yaitu, if bool(L):) karena itu tersirat. Tetapi, untuk kasus-kasus ketika "tidak kosong" secara eksplisit diperlukan sebagai fungsi, booladalah pilihan terbaik.

Vedran Šego
sumber
1

Untuk memeriksa apakah daftar kosong atau tidak, Anda dapat menggunakan dua cara berikut. Tapi ingat, kita harus menghindari cara memeriksa jenis urutan secara eksplisit (ini less pythoniccara):

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

Cara kedua adalah more pythonicsatu. Metode ini merupakan cara pemeriksaan tersirat dan jauh lebih disukai daripada yang sebelumnya.

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"

Semoga ini membantu.

Andy
sumber