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.
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.
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.
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:
ifnot 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.
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)
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.
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:
ifnot 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 :)
Untuk skala, inilah biaya memanggil fungsi dan membangun dan mengembalikan daftar kosong, yang dapat Anda kurangi dari biaya pemeriksaan kekosongan yang digunakan di atas:
Kami melihat bahwa baik pengecekan untuk panjang dengan fungsi builtin lendibandingkan dengan 0atau 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):
Dan untuk [] == []itu harus membangun daftar yang tidak perlu dan kemudian, sekali lagi, lakukan operasi perbandingan di mesin virtual Python (sebagai lawan dari C)
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.
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 notnot 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:pass22.6 ns ±0.963 ns per loop (mean ± std. dev. of 7 runs,10000000 loops each)In[6]:%timeit ifnot l:pass24.4 ns ±0.796 ns per loop (mean ± std. dev. of 7 runs,10000000 loops each)In[7]:%timeit ifnotnot l:pass23.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:pass23.7 ns ±1.06 ns per loop (mean ± std. dev. of 7 runs,10000000 loops each)In[10]:%timeit ifnot l:pass23.6 ns ±1.64 ns per loop (mean ± std. dev. of 7 runs,10000000 loops each)In[11]:%timeit ifnotnot l:pass26.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.
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.
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.
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.
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
66
len()adalah operasi O (1) untuk daftar, string, dikte, dan set Python. Python secara internal melacak jumlah elemen dalam wadah ini.
if isinstance(a,(list, some, other, types, i, accept))andnot 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)andnot a.size:
do_stuff
elif isinstance(a, collections.Sized)andnot a:
do_stuff
tes pertama adalah jawaban atas jawaban @ Mike di atas. Baris ketiga juga bisa diganti dengan:
elif isinstance(a,(list, tuple))andnot a:
jika Anda hanya ingin menerima contoh jenis tertentu (dan subtipe mereka), atau dengan:
elif isinstance(a,(list, tuple))andnot 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.
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. "
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:
@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:
ifnot 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 elementsexceptStopIteration:print("Error: a is empty")
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.
def list_test (L):if L isNone:print('list is None')elifnot 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 isNone
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):ifnot L :print('list is empty')else:print('list has %d elements'% len(L))
list_test2(None)
list_test2([])
list_test2([1,2,3])
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")
-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:returnFalseelse:return all(bool(x)for x in l)
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.)
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.
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.')returnTrueelse:print('Structure is empty.')returnFalse
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).
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.
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.
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:return0else:return1# ––––––––––––––––––––––––––––––––
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):ifnot list1:returnTrueelse:returnFalse# ––––––––––––––––––––––––––––––––
list1 =[]if enquiry(list1):print("The list is Empty")else:print("The list isn't empty")# Result: "The list is Empty"
if a == []
memaksa jenis tertentu (() == []
adalahFalse
). 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__ )Cara pythonic untuk melakukannya adalah dari panduan gaya PEP 8 (di mana Ya berarti "disarankan" dan Tidak berarti "tidak dianjurkan"):
sumber
seq
diharapkan menjadi semacam objek daftar.Saya lebih suka secara eksplisit:
Dengan cara ini 100% jelas itu
li
adalah urutan (daftar) dan kami ingin menguji ukurannya. Masalah saya denganif not li: ...
itu memberi kesan salah yaituli
variabel boolean.sumber
li
itu bool sama sekali, dan tidak peduli. Jika ini penting, Anda harus menambahkan komentar, bukan kode lagi.None
atau0
untuk 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.if bool(len(li) == 0) is True:
?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
list
s 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
bool
s, danif x
mencoba untuk mengevaluasi semuabool
itu sekaligus untuk beberapa jenis nilai kebenaran agregat. Tetapi ini tidak masuk akal, jadi Anda mendapatkanValueError
: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,
if
pernyataan itu akan "berfungsi", dalam arti bahwa Anda tidak mendapatkan kesalahan. Namun, jika satu elemen tersebut kebetulan0
(0.0
atauFalse
, ...),if
pernyataan tersebut akan menghasilkanFalse
:Tetapi jelas
x
ada dan tidak kosong! Hasil ini bukan yang Anda inginkan.Menggunakan
len
dapat memberikan hasil yang tidak terdugaSebagai contoh,
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
:Jika Anda tidak yakin apakah itu mungkin
list
array, 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 pilihdtype
. 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 :Ini akan membuat
x.size
pemeriksaan berfungsi dalam semua kasus yang saya lihat di halaman ini.sumber
numpy
-numpy
adalah 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 yangpathlib
digunakan/
untuk menggabungkan jalur bukannya+
- itu tidak standar, tetapi masuk akal dalam konteks.if x
danlen(x)
- dan kadang-kadang kerusakan itu sangat sulit untuk dideteksi dan didebug.Jawaban singkat:
Tempatkan daftar dalam konteks boolean (misalnya, dengan
if
atauwhile
pernyataan). Ini akan mengujiFalse
apakah itu kosong, danTrue
sebaliknya. Sebagai contoh:PEP 8
PEP 8 , panduan gaya Python resmi untuk kode Python di pustaka standar Python, menegaskan:
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:
Dan pengguna bahasa yang malas mungkin tergoda untuk melakukan ini:
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,
[]
):Dan dokumentasi model data:
dan
Jadi alih-alih ini:
atau ini:
Melakukan hal ini:
Melakukan apa yang Pythonic biasanya terbayar dalam kinerja:
Apakah itu membuahkan hasil? (Perhatikan bahwa lebih sedikit waktu untuk melakukan operasi yang setara lebih baik :)
Untuk skala, inilah biaya memanggil fungsi dan membangun dan mengembalikan daftar kosong, yang dapat Anda kurangi dari biaya pemeriksaan kekosongan yang digunakan di atas:
Kami melihat bahwa baik pengecekan untuk panjang dengan fungsi builtin
len
dibandingkan dengan0
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):Dan untuk
[] == []
itu harus membangun daftar yang tidak perlu dan kemudian, sekali lagi, lakukan operasi perbandingan di mesin virtual Python (sebagai lawan dari C)Cara "Pythonic" adalah pemeriksaan yang jauh lebih sederhana dan lebih cepat karena panjang daftar di-cache di header instance objek:
Bukti dari sumber C dan dokumentasi
Dari sumber c di Sertakan / listobject.h :
Tanggapan terhadap komentar:
IPython magic,,
%timeit
tidak sepenuhnya tidak berguna di sini:Kita dapat melihat ada sedikit biaya linear untuk setiap tambahan di
not
sini. Kami ingin melihat biaya, ceteris paribus , yaitu, semuanya sama - di mana semuanya diminimalisasi sejauh mungkin:Sekarang mari kita lihat case untuk daftar pengangguran:
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.
sumber
l=[]
kemudian%timeit len(l) != 0
90,6 ns ± 8,3 ns,%timeit l != []
55,6 ns ± 3,09,%timeit not not l
38,5 ns ± 0,372. Tapi tidak mungkin ada orang yang bisa menikmatinot not l
meskipun kecepatannya tiga kali lipat. Itu terlihat konyol. Tetapi kecepatan menangif 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 l
tidak berguna karena tidak ada konversi yang akan terjadi.Daftar kosong sendiri dianggap salah dalam pengujian nilai sebenarnya (lihat dokumentasi python ):
@ Daren Thomas
DuckCollection Anda harus menerapkan
__nonzero__
atau__len__
lebih jika a: akan bekerja tanpa masalah.sumber
[] == False
akan mengevaluasi ke False meskipunbool()
.bool([]) == False
akan mengevaluasiTrue
seperti yang diharapkan.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 dariNone
, 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", sedangkanif 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.sumber
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.
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.
sumber
<rest of code>
yang mungkin menggunakan hasil darifor
loop? Atau langsung menggunakan beberapa nilaia
? 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.len()
adalah operasi O (1) untuk daftar, string, dikte, dan set Python. Python secara internal melacak jumlah elemen dalam wadah ini.JavaScript memiliki gagasan yang sama tentang kebenaran / kepalsuan .
sumber
Saya telah menulis:
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
, misalnyaFalse
, Anda memerlukan tes yang lebih ketat daripada hanyaif not a:
. Anda dapat menggunakan sesuatu seperti ini:tes pertama adalah jawaban atas jawaban @ Mike di atas. Baris ketiga juga bisa diganti dengan:
jika Anda hanya ingin menerima contoh jenis tertentu (dan subtipe mereka), atau dengan:
Anda bisa pergi tanpa pemeriksaan tipe eksplisit, tetapi hanya jika konteks sekitarnya sudah meyakinkan Anda bahwa itu
a
adalah nilai dari tipe yang siap Anda tangani, atau jika Anda yakin bahwa tipe yang tidak siap Anda tangani akan berjalan untuk meningkatkan kesalahan (misalnya,TypeError
jika Anda memanggillen
nilai 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.sumber
collections.abc.Sized
ataucollections.abc.Sequence
, tapi mungkin itu yang Anda tulis sendiri danregister(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.[]
dan bukan sesuatu yang salah dari tipe lain, maka pasti diperlukanif a == []:
, daripada mucking tentang dengan isinstance.==
. Dari atas kepala saya, saya tidak dapat mengidentifikasi untuk[]
.[] == ()
misalnya pengembalianFalse
. Tetapi misalnyafrozenset()==set()
kembaliTrue
. Jadi ada baiknya setidaknya memikirkan apakah beberapa tipe yang tidak diinginkan mungkin dipaksa[]
(atau sebaliknya) saat melakukannyaa == []
.Dari dokumentasi pengujian nilai kebenaran:
Semua nilai selain dari yang tercantum di sini dipertimbangkan
True
None
False
0
,0.0
,0j
.''
,()
,[]
.{}
,.__bool__()
atau__len__()
, ketika metode itu mengembalikan nilai integer nol atau boolFalse
.Seperti yang dapat dilihat, daftar kosong
[]
adalah palsu , jadi melakukan apa yang akan dilakukan pada nilai boolean terdengar paling efisien:sumber
assert(not myList)
. Jika Anda juga ingin menegaskan objek adalahlist
, Anda dapat menggunakanassertIsInstance()
.Berikut adalah beberapa cara Anda dapat memeriksa apakah daftar kosong:
1) Cara pythonic yang cukup sederhana:
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 ). DanTrue
nilai akan menunjukkan bahwa itu tidak kosong.2) Cara yang lebih eksplisit: gunakan
len()
untuk menemukan panjang dan periksa apakah sama dengan0
:3) Atau membandingkannya dengan daftar kosong anonim:
4) Cara lain yang konyol untuk dilakukan adalah menggunakan
exception
daniter()
:sumber
Saya lebih suka yang berikut ini:
sumber
if not a:
dan lebih mudah rusak. Tolong jangan lakukan itu.() == []
juga sama dengan false. Meskipun saya suka bagaimana implementasi ini membacaif not a:
sampul semua kasus, jika Anda benar-benar mengharapkan daftar maka contoh Anda harus cukup.Metode 1 (Lebih disukai):
Metode 2:
Metode 3:
sumber
Kadang-kadang baik untuk menguji
None
dan untuk kekosongan secara terpisah karena mereka adalah dua keadaan yang berbeda. Kode di atas menghasilkan output berikut:Meskipun tidak ada nilainya yang
None
palsu. Jadi jika Anda tidak ingin memisahkan tes untukNone
-ness, Anda tidak perlu melakukan itu.menghasilkan yang diharapkan
sumber
Banyak jawaban telah diberikan, dan banyak dari mereka cukup bagus. Saya hanya ingin menambahkan cek itu
juga akan lulus
None
dan jenis struktur kosong lainnya. Jika Anda benar-benar ingin memeriksa daftar kosong, Anda dapat melakukan ini:sumber
a
bukan daftar dana
tidak ada metode yang__len__
diterapkan. Saya akan merekomendasikan:if isinstance(obj, list): if len(obj) == 0: print '...'
and
malas dengan Python. Tidak adaand
yang akan dieksekusi jika kondisi sebelumnyaand
salah.kita bisa menggunakan yang sederhana jika lain:
sumber
Jika Anda ingin memeriksa apakah daftar kosong:
Jika Anda ingin memeriksa apakah semua nilai dalam daftar kosong. Namun itu
True
untuk daftar kosong:Jika Anda ingin menggunakan kedua kasus bersama-sama:
Sekarang Anda dapat menggunakan:
sumber
Terinspirasi oleh solusi @ dubiousjim, saya mengusulkan untuk menggunakan pemeriksaan umum tambahan apakah itu sesuatu yang dapat diubah
Catatan: string dianggap iterable. - tambahkan
and not isinstance(a,(str,unicode))
jika Anda ingin string kosong dikecualikanUji:
sumber
if a:
, itu karena saya ingin pengecualian jikaa
bukan semacam wadah. (Menjadi pengulangan juga memungkinkan pengulangan, yang tidak bisa diuji dengan sia-sia.)sedikit lebih praktis:
dan versi shertest:
sumber
Dari python3 dan seterusnya, Anda dapat menggunakan
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
sumber
a
ada kosong atau tidak.pythonic
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==[])
Anda bahkan dapat mencoba menggunakan bool () seperti ini
Saya suka cara ini karena daftar periksa kosong atau tidak.
Sangat berguna dan bermanfaat.
sumber
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.Cukup gunakan is_empty () atau buat fungsi seperti: -
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)
.sumber
is_empty
menunjukkan bahwa ia mengembalikan sesuatu. Tetapi jika itu terjadi, sesuatu itu akan terjadibool(any_structure)
, yang harus Anda gunakan sebagai gantinya ( ketika Anda membutuhkannyabool
).bool
itu (juga) mencetak pesan ke output standar?bool
variabel kembali . Pilihan ada pada Anda. Saya menulis keduanya sehingga Anda dapat memilih di antara mereka.Cara sederhana adalah memeriksa panjangnya sama dengan nol.
sumber
Nilai kebenaran dari daftar kosong adalah
False
sedangkan untuk daftar tidak kosong ituTrue
.sumber
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):
Dan, tentu saja, ada cara yang sangat alami untuk melakukannya:
Tentu saja, jangan tidak menggunakan
bool
diif
(yaitu,if bool(L):
) karena itu tersirat. Tetapi, untuk kasus-kasus ketika "tidak kosong" secara eksplisit diperlukan sebagai fungsi,bool
adalah pilihan terbaik.sumber
Semoga ini membantu.
sumber