Saat ini saya melakukan ini:
try:
something = iterator.next()
# ...
except StopIteration:
# ...
Tapi saya ingin ekspresi yang bisa saya tempatkan di dalam if
pernyataan sederhana . Apakah ada fitur bawaan yang dapat membuat kode ini terlihat tidak terlalu kikuk?
any()
mengembalikan False
jika sebuah iterable kosong, tetapi itu akan berpotensi mengulang semua item jika tidak. Saya hanya perlu untuk memeriksa item pertama.
Seseorang bertanya apa yang saya coba lakukan. Saya telah menulis sebuah fungsi yang mengeksekusi query SQL dan menghasilkan hasilnya. Terkadang ketika saya memanggil fungsi ini, saya hanya ingin tahu apakah kueri mengembalikan sesuatu dan membuat keputusan berdasarkan itu.
Jawaban:
any
tidak akan melampaui elemen pertama jika True. Jika iterator menghasilkan sesuatu yang salah, Anda dapat menulisany(True for _ in iterator)
.sumber
any((x > 100 for x in xrange(10000000)))
dan kemudian jalankanany((x > 10000000 for x in xrange(100000000)))
- yang kedua akan memakan waktu lebih lama.sum(1 for _ in itertools.islice(iterator, max_len)) >= max_len
all(False for _ in iterator)
akan memeriksa apakah iterator kosong. (semua mengembalikan True jika iterator kosong, jika tidak maka berhenti ketika melihat elemen False pertama)Dalam Python 2.6+, jika nama
sentinel
terikat pada nilai yang tidak mungkin dihasilkan oleh iterator,Jika Anda tidak tahu apa yang mungkin dihasilkan oleh iterator, buatlah sentinel Anda sendiri (misalnya di bagian atas modul Anda) dengan
Jika tidak, Anda dapat menggunakan, dalam peran sentinel, nilai apa pun yang "Anda ketahui" (berdasarkan pertimbangan aplikasi) yang tidak mungkin dihasilkan oleh iterator.
sumber
if not next(iterator, None):
sudah cukup karena saya yakin Tidak Ada tidak akan menjadi bagian dari item. Terima kasih telah mengarahkan saya ke arah yang benar!not
akan mengembalikan True untuk objek falsy apa pun, seperti daftar kosong, False, dan nol.is not None
lebih aman, dan menurut saya lebih jelas.Ini tidak benar-benar lebih bersih, tetapi ini menunjukkan cara untuk mengemasnya dalam fungsi tanpa kehilangan:
Ini tidak benar-benar pythonic, dan untuk kasus tertentu, mungkin ada solusi yang lebih baik (tapi kurang umum), seperti default berikutnya .
Ini tidak umum karena Tidak Ada dapat menjadi elemen yang valid di banyak iterable.
sumber
next()
.tee
dalam harus menyimpan setiap elemen dari iterator asli jikaany_check
perlu maju. Ini lebih buruk daripada hanya mengubah iterator asli menjadi sebuah daftar.kamu bisa memakai:
tapi itu agak tidak jelas untuk pembaca kode
sumber
Cara terbaik untuk melakukannya adalah dengan
peekable
darimore_itertools
.Berhati-hatilah jika Anda menyimpan referensi ke iterator lama, iterator itu akan menjadi maju. Anda harus menggunakan iterator baru yang dapat diintip sejak saat itu. Sungguh, meskipun, peekable berharap menjadi satu-satunya kode yang memodifikasi iterator lama itu, jadi Anda tidak boleh menyimpan referensi ke iterator lama yang ada di sekitar.
sumber
Bagaimana dengan:
sumber
class NotSet: pass
, lalu periksaif next(i, NotSet) is NotSet: print("Iterator is empty")
__length_hint__
memperkirakan panjanglist(it)
- itu metode pribadi, meskipun:sumber
Ini adalah pembungkus iterator berlebihan yang umumnya memungkinkan untuk memeriksa apakah ada item berikutnya (melalui konversi ke boolean). Tentu sangat tidak efisien.
Keluaran:
sumber
Sedikit terlambat, tapi ... Anda dapat mengubah iterator menjadi daftar dan kemudian bekerja dengan daftar itu:
sumber