Saya memiliki fungsi generator seperti berikut:
def myfunct():
...
yield result
Cara biasa memanggil fungsi ini adalah:
for r in myfunct():
dostuff(r)
Pertanyaan saya, apakah ada cara untuk mendapatkan hanya satu elemen dari generator kapan saja saya suka? Misalnya, saya ingin melakukan sesuatu seperti:
while True:
...
if something:
my_element = pick_just_one_element(myfunct())
dostuff(my_element)
...
python
iterator
generator
python-2.x
Alexandros
sumber
sumber
next(gen, default)
dapat juga digunakan untuk menghindariStopIteration
pengecualian. Misalnyanext(g, None)
untuk generator string akan menghasilkan string atau Tidak ada setelah iterasi selesai.next(g)
,. Ini secara internal akan memanggilg.__next__()
, tetapi Anda tidak benar-benar perlu khawatir tentang hal itu, sama seperti Anda biasanya tidak peduli bahwalen(a)
panggilan internala.__len__()
.g.next()
adag.__next__()
di py3k. Builtinnext(iterator)
sudah ada sejak Python 2.6, dan itulah yang harus digunakan di semua kode Python baru, dan itu sepele untuk backimplement jika Anda perlu mendukung py <= 2.5.Untuk memilih hanya satu elemen penggunaan generator
break
dalamfor
pernyataan, ataulist(itertools.islice(gen, 1))
Menurut contoh Anda (secara harfiah) Anda dapat melakukan sesuatu seperti:
Jika Anda ingin " dapatkan hanya satu elemen dari generator [yang pernah dihasilkan] kapan pun saya suka " (saya kira 50% itulah niat asli, dan niat paling umum) maka:
Dengan cara ini penggunaan eksplisit
generator.next()
dapat dihindari, dan penanganan akhir input tidak memerlukan penanganan (samar)StopIteration
pengecualian atau perbandingan nilai standar ekstra.The
else:
darifor
bagian pernyataan hanya diperlukan jika Anda ingin melakukan sesuatu yang istimewa dalam kasus akhir-of-generator.Catatan pada
next()
/.next()
:Dalam Python3
.next()
metode ini berganti nama menjadi.__next__()
untuk alasan yang baik: itu dianggap tingkat rendah (PEP 3114). Sebelum Python 2.6, fungsi bawaannext()
tidak ada. Dan itu bahkan dibahas untuk pindahnext()
keoperator
modul (yang seharusnya bijaksana), karena kebutuhannya yang langka dan inflasi yang meragukan dari nama-nama asli.Menggunakan
next()
tanpa default masih merupakan praktik tingkat sangat rendah - melempar crypticStopIteration
seperti baut keluar dari biru dalam kode aplikasi normal secara terbuka. Dan menggunakannext()
dengan sentinel default - yang terbaik harus menjadi satu-satunya pilihan untuknext()
langsung masukbuiltins
- terbatas dan sering memberikan alasan untuk logika / keterbacaan non-pythonic.Intinya: Menggunakan next () harus sangat jarang - seperti menggunakan fungsi
operator
modul. Menggunakanfor x in iterator
,islice
,list(iterator)
dan fungsi lainnya menerima iterator mulus adalah cara alami menggunakan iterator pada level aplikasi - dan cukup selalu mungkin.next()
adalah level rendah, konsep tambahan, tidak terlihat - seperti yang diperlihatkan oleh pertanyaan dari utas ini. Sedangkan misalnya menggunakanbreak
dalamfor
adalah konvensional.sumber
mySeq.head
?Saya tidak percaya ada cara mudah untuk mengambil nilai sewenang-wenang dari generator. Generator akan menyediakan metode () berikutnya untuk melintasi sendiri, tetapi urutan penuh tidak segera diproduksi untuk menghemat memori. Itulah perbedaan fungsional antara generator dan daftar.
sumber
Bagi Anda yang memindai jawaban ini untuk contoh kerja lengkap untuk Python3 ... baik di sini ya pergi:
Output ini:
sumber
Generator adalah fungsi yang menghasilkan iterator. Oleh karena itu, setelah Anda memiliki instance iterator, gunakan next () untuk mengambil item berikutnya dari iterator. Sebagai contoh, gunakan fungsi next () untuk mengambil item pertama, dan kemudian gunakan
for in
untuk memproses item yang tersisa:sumber
pastikan untuk menangkap pengecualian yang dilemparkan setelah elemen terakhir diambil
sumber
Saya percaya satu-satunya cara adalah mendapatkan daftar dari iterator kemudian mendapatkan elemen yang Anda inginkan dari daftar itu.
sumber
myfunct()
menghasilkan sejumlah besar nilai) karena Anda dapat menggunakan fungsi bawaannext
untuk mendapatkan nilai yang dihasilkan selanjutnya.