Generator Function, yield & next()
Generator Function
Pada materi sebelumnya, kita telah mempelajari bahwa generator digunakan untuk menghasilkan nilai secara bertahap.
Sekarang kita akan mempelajari bagaimana membuat generator sendiri menggunakan generator function, bagaimana yield bekerja, serta bagaimana mengambil nilai dari generator menggunakan next().
Iterable, Iteration, dan Generator
Sebelum memahami generator secara lebih mendalam, penting untuk membedakan tiga istilah:
- Iterable adalah object yang dapat diiterasi atau diproses satu per satu.
- Iteration adalah proses mengambil elemen dari iterable secara berurutan.
- Generator adalah salah satu jenis object yang dapat menghasilkan nilai secara bertahap.
Contoh iterable yang umum digunakan di Python:
listtuplestringdictionarysetrange- generator
Hubungan sederhananya:
Iterable
↓
dapat dilakukan iteration
↓
menghasilkan nilai satu per satu
Generator merupakan salah satu jenis iterable.
Semua generator dapat digunakan sebagai iterable, tetapi tidak semua iterable merupakan generator.
Contohnya, list adalah iterable tetapi bukan generator.
Iterable
├── list
├── tuple
├── string
├── set
├── dictionary
├── range
└── generator
Iteration
Iteration merupakan proses mengambil nilai dari sebuah iterable secara berurutan.
Contoh paling umum adalah menggunakan for:
numbers = [1, 2, 3]
for number in numbers:
print(number)
Proses tersebut mengambil nilai:
1
↓
2
↓
3
Python menangani mekanisme iterasinya sehingga kita dapat menggunakan for tanpa harus mengelola proses pengambilan nilai secara manual.
Generator juga dapat digunakan dalam proses tersebut.
Membuat Generator Function
Generator function adalah function yang menggunakan keyword yield untuk menghasilkan nilai secara bertahap.
Contoh:
def generator_function(num):
for i in range(num):
yield i * 2
Berbeda dengan function biasa yang menggunakan return, function tersebut menggunakan:
yield i * 2
Hal ini membuat function tersebut menjadi generator function.
Ketika generator function dipanggil, prosesnya tidak langsung menghasilkan seluruh nilai sekaligus.
Generator akan menghasilkan nilai ketika diminta.
Keyword yield
yield digunakan untuk menghasilkan nilai dari generator.
Salah satu karakteristik penting yield adalah kemampuannya untuk menjeda sementara eksekusi function.
Misalnya:
def generator_function(num):
for i in range(num):
yield i * 2
Ketika generator menghasilkan nilai pertama, proses function berhenti sementara pada posisi yield.
Ketika nilai berikutnya diminta, function melanjutkan eksekusi dari posisi terakhir.
Secara sederhana:
Generator dijalankan
↓
yield nilai pertama
↓
Pause
↓
Minta nilai berikutnya
↓
Lanjutkan eksekusi
↓
yield nilai berikutnya
↓
Pause kembali
Generator Function vs Function Biasa
Perbedaan penting antara function biasa dan generator function adalah cara menghasilkan hasil.
Function biasa dengan return:
def get_numbers():
return [1, 2, 3]
Seluruh hasil tersedia sekaligus.
Sedangkan generator:
def get_numbers():
yield 1
yield 2
yield 3
Nilai dihasilkan secara bertahap.
Secara sederhana:
return
↓
mengembalikan hasil
↓
function selesai
yield
↓
menghasilkan nilai
↓
pause
↓
dapat dilanjutkan
Menggunakan Generator dengan for
Generator dapat digunakan langsung dalam perulangan for.
Contohnya:
def generator_function(num):
for i in range(num):
yield i * 2
for item in generator_function(10):
print(item)
Output:
0
2
4
6
8
10
12
14
16
18
Generator menghasilkan nilai satu per satu selama proses iterasi berlangsung.
Fungsi next()
Selain menggunakan for, kita dapat mengambil nilai generator secara manual menggunakan fungsi bawaan next().
Contoh:
def generator_function(num):
for i in range(num):
yield i * 2
g = generator_function(100)
print(next(g))
print(next(g))
print(next(g))
Output:
0
2
4
Setiap pemanggilan next() meminta generator untuk menghasilkan nilai berikutnya.
State Retention
Salah satu karakteristik penting generator adalah kemampuannya untuk mengingat state atau keadaan eksekusi terakhir.
Perhatikan:
g = generator_function(100)
print(next(g))
print(next(g))
print(next(g))
Pemanggilan pertama:
next(g)
menghasilkan:
0
Pemanggilan kedua:
next(g)
menghasilkan:
2
Pemanggilan ketiga:
next(g)
menghasilkan:
4
Generator tidak kembali ke awal setiap kali next() dipanggil.
Generator melanjutkan proses dari posisi terakhir.
Secara sederhana:
next(g)
↓
0
↓
pause
next(g)
↓
2
↓
pause
next(g)
↓
4
↓
pause
Kemampuan untuk mempertahankan state inilah yang memungkinkan generator menghasilkan sequence secara bertahap.
StopIteration
Generator memiliki jumlah nilai yang terbatas apabila proses di dalamnya juga memiliki batas.
Ketika seluruh nilai telah dihasilkan dan kita masih memanggil next(), Python akan menghasilkan exception StopIteration.
Contoh:
def generator_function(num):
for i in range(num):
yield i * 2
g = generator_function(1)
print(next(g))
print(next(g))
Pemanggilan pertama menghasilkan:
0
Namun pemanggilan kedua akan menghasilkan:
StopIteration
Hal tersebut terjadi karena generator hanya memiliki satu nilai untuk dihasilkan.
Secara sederhana:
Generator
↓
0
↓
Tidak ada nilai lagi
↓
StopIteration
StopIteration merupakan tanda bahwa iterator atau generator sudah tidak memiliki nilai berikutnya.
StopIteration pada for Loop
Ketika menggunakan for, kita biasanya tidak melihat exception StopIteration.
Contohnya:
def generator_function(num):
for i in range(num):
yield i * 2
for item in generator_function(3):
print(item)
Output:
0
2
4
Setelah semua nilai dihasilkan, perulangan berhenti secara otomatis.
Secara internal, mekanisme iterasi mengetahui bahwa generator sudah tidak memiliki nilai berikutnya dan menangani kondisi tersebut sehingga for dapat berhenti dengan normal.
Dengan demikian:
next()
↓
tidak ada nilai
↓
StopIteration
sedangkan pada for:
for
↓
mengambil nilai
↓
mengambil nilai
↓
tidak ada nilai
↓
berhenti secara otomatis
Generator dan Memory
Generator tidak membuat seluruh sequence hasil sekaligus.
Contohnya:
def generator_function(num):
for i in range(num):
yield i * 2
Jika num memiliki nilai yang sangat besar, generator tetap menghasilkan nilai secara bertahap.
Hal ini berbeda dengan membuat list yang berisi seluruh hasil.
Konsepnya:
List
↓
Buat semua hasil
↓
Simpan semua hasil
Generator
↓
Hasilkan nilai
↓
Gunakan
↓
Hasilkan nilai berikutnya
Pendekatan generator dapat membantu menghemat penggunaan memory ketika bekerja dengan sequence yang besar.
Generator sebagai Iterator
Generator juga memiliki karakteristik iterator karena dapat menghasilkan nilai secara berurutan menggunakan mekanisme iterasi.
Hubungannya dapat digambarkan:
Iterable
↓
Iterator
↓
Generator
Generator dapat digunakan dalam for dan dapat mengambil nilai berikutnya menggunakan next().
Karena itu, memahami generator juga membantu memperjelas hubungan antara iterable, iterator, dan generator yang telah dibahas sebelumnya.
Kesimpulan
Generator function adalah function yang menggunakan yield untuk menghasilkan nilai secara bertahap.
Konsep penting yang perlu diingat:
yieldmenghasilkan nilai dan menjeda sementara eksekusi generator.- Generator dapat melanjutkan eksekusi dari posisi terakhir.
next()digunakan untuk mengambil nilai berikutnya secara manual.- Generator mempertahankan state selama proses iterasi.
StopIterationmenunjukkan bahwa generator sudah tidak memiliki nilai berikutnya.formenangani proses iterasi generator secara otomatis.- Generator dapat membantu menghemat memory karena nilai dihasilkan secara bertahap.
Alur sederhananya:
Generator Function
↓
yield
↓
Hasilkan nilai
↓
Pause
↓
next()
↓
Lanjutkan
↓
Hasilkan nilai berikutnya
↓
...
↓
Tidak ada nilai
↓
StopIteration
Konsep berikutnya yang penting untuk dipelajari adalah perbedaan lebih mendalam antara generator, iterator, dan iterable, serta bagaimana generator dapat digunakan dalam pemrosesan data secara efisien.