Mengenal Generator dalam Python
Bahasa pemrograman Python memiliki berbagai fitur yang dirancang untuk mempermudah pengolahan data, mulai dari operasi sederhana hingga pemrosesan informasi dalam jumlah besar. Salah satu fitur yang menarik untuk dipelajari adalah generator. Fitur ini memungkinkan sebuah program menghasilkan nilai secara bertahap tanpa harus menyimpan seluruh hasil dalam sebuah kumpulan data terlebih dahulu. Dengan pendekatan tersebut, program dapat mengambil nilai ketika diperlukan sehingga proses pengolahan data menjadi lebih fleksibel.
Sebelum lebih lanjut mempelajari materi tentang Mengenal Generator dalam Python, terlebih dahulu pelajari materi tentang: List Comprehension dalam Python, Fungsi Anonim dalam Python, dan Memahami Iterator dalam Python.
Sebelum lebih lanjut mempelajari materi tentang Mengenal Generator dalam Python, terlebih dahulu pelajari materi tentang: List Comprehension dalam Python, Fungsi Anonim dalam Python, dan Memahami Iterator dalam Python.
Dalam pemrograman, terdapat banyak situasi ketika suatu program perlu menghasilkan rangkaian nilai. Misalnya, program membutuhkan deret bilangan, menghitung pangkat suatu angka, membaca data dari berkas, mengolah nilai siswa, atau memproses hasil perhitungan secara berurutan. Salah satu cara untuk memenuhi kebutuhan tersebut adalah membuat daftar yang berisi seluruh hasil perhitungan. Akan tetapi, pendekatan tersebut tidak selalu menjadi pilihan terbaik, terutama ketika jumlah hasil yang dihasilkan sangat banyak.
Generator menawarkan pendekatan berbeda. Alih-alih menghasilkan seluruh nilai sekaligus, generator dapat memberikan satu nilai, menghentikan sementara prosesnya, kemudian melanjutkan pekerjaan ketika nilai berikutnya diminta. Mekanisme ini memungkinkan program mengolah data secara bertahap dengan kebutuhan penyimpanan yang berpotensi lebih kecil.
Generator juga berkaitan erat dengan konsep iterator dalam Python. Iterator merupakan objek yang menyediakan nilai berikutnya ketika diminta, sedangkan generator merupakan salah satu cara praktis untuk membuat iterator. Melalui generator, pemrogram tidak perlu selalu membuat kelas khusus beserta metode pengambilan nilai secara manual. Cukup dengan menggunakan fungsi dan kata kunci `yield`, rangkaian nilai dapat dihasilkan melalui kode yang lebih ringkas.
Pemahaman tentang generator bermanfaat bagi siapa pun yang mempelajari Python, baik pada tingkat dasar maupun lanjutan. Konsep ini membantu menjelaskan cara kerja pengambilan nilai secara bertahap, penggunaan memori, pengolahan data berukuran besar, serta penyusunan beberapa proses pengolahan data secara berurutan. Oleh karena itu, pembahasan generator perlu mencakup pengertian, karakteristik, cara pembuatan, perbedaannya dengan fungsi biasa dan iterator, hingga penerapannya dalam program.
Berbeda dengan fungsi biasa yang umumnya menggunakan `return` untuk mengembalikan hasil dan mengakhiri pelaksanaan fungsi, generator menggunakan kata kunci `yield` untuk menghasilkan nilai sekaligus menangguhkan sementara pelaksanaan fungsi. Setelah sebuah nilai diberikan, generator mempertahankan keadaan pelaksanaannya sehingga proses dapat dilanjutkan dari posisi terakhir ketika nilai berikutnya diminta.
Misalnya, sebuah program perlu menghasilkan angka 1, 2, 3, 4, dan 5. Salah satu pendekatan adalah menyimpan semua angka tersebut dalam sebuah daftar. Pendekatan lain adalah menggunakan generator yang menghasilkan angka satu per satu sesuai kebutuhan.
Contoh fungsi generator dapat ditulis sebagai berikut:
def deret_angka():
yield 1
yield 2
yield 3
yield 4
yield 5
for angka in deret_angka():
print(angka)
Hasil program:
1
2
3
4
5
Pada contoh tersebut, fungsi `deret_angka()` menggunakan kata kunci `yield` untuk menghasilkan lima nilai. Setiap kali generator diminta melanjutkan proses, fungsi menghasilkan nilai berikutnya sesuai urutan pernyataan `yield`.
Perulangan `for` kemudian mengambil setiap nilai dari objek generator dan menampilkannya. Setelah seluruh nilai dihasilkan, proses pengulangan berakhir secara otomatis.
Contoh tersebut memperlihatkan bahwa generator dapat digunakan untuk menghasilkan rangkaian nilai tanpa harus membuat daftar terlebih dahulu. Walaupun contoh lima angka terlihat sederhana, prinsip yang sama dapat diterapkan pada proses pengolahan data yang lebih kompleks.
Untuk memahami mekanisme tersebut, perhatikan contoh berikut:
def contoh_generator():
print("Proses dimulai")
yield 10
print("Proses dilanjutkan")
yield 20
print("Proses berakhir")
yield 30
hasil = contoh_generator()
print(next(hasil))
print(next(hasil))
print(next(hasil))
Hasil program:
Proses dimulai
10
Proses dilanjutkan
20
Proses berakhir
30
Ketika fungsi `contoh_generator()` dipanggil, Python tidak langsung menjalankan seluruh isi fungsi. Pemanggilan tersebut menghasilkan objek generator. Pelaksanaan isi fungsi baru dimulai ketika program meminta nilai, misalnya melalui `next()`.
Pada pemanggilan pertama, generator menjalankan perintah `print("Proses dimulai")`, kemudian menghasilkan nilai 10 melalui `yield`. Pelaksanaan fungsi berhenti sementara pada titik tersebut.
Ketika `next(hasil)` dipanggil kembali, fungsi melanjutkan proses dari posisi terakhir. Pernyataan yang menampilkan teks `Proses dilanjutkan` dijalankan, kemudian generator menghasilkan nilai 20. Pada pemanggilan ketiga, proses dilanjutkan kembali hingga menghasilkan nilai 30.
Contoh tersebut menunjukkan bahwa `yield` bukan sekadar perintah untuk memberikan hasil. Kata kunci ini juga memungkinkan generator mempertahankan keadaan pelaksanaannya, termasuk variabel lokal dan posisi proses, selama generator belum selesai.
Ketika generator mencapai akhir fungsi tanpa menghasilkan nilai tambahan, iterator generator menjadi habis. Pemanggilan `next()` berikutnya akan menimbulkan `StopIteration`, sedangkan perulangan `for` akan berhenti secara otomatis.
Kata kunci `return` digunakan untuk mengembalikan hasil dan mengakhiri pelaksanaan fungsi. Setelah pernyataan `return` dijalankan, fungsi biasa tidak melanjutkan perintah yang berada setelahnya dalam pemanggilan tersebut.
Sebaliknya, `yield` memberikan nilai sambil menangguhkan pelaksanaan fungsi generator. Generator dapat dilanjutkan kembali ketika program meminta nilai berikutnya.
Perhatikan contoh fungsi biasa berikut:
def fungsi_biasa():
return 10
return 20
print(fungsi_biasa())
Hasil program:
10
Fungsi tersebut hanya mengembalikan angka 10. Pernyataan `return 20` tidak dijalankan karena fungsi telah berakhir setelah pernyataan `return` pertama.
Bandingkan dengan contoh generator berikut:
def fungsi_generator():
yield 10
yield 20
for nilai in fungsi_generator():
print(nilai)
Hasil program:
10
20
Generator tersebut dapat menghasilkan kedua nilai karena `yield` tidak langsung mengakhiri fungsi. Pelaksanaan ditangguhkan setelah nilai 10 diberikan, kemudian dilanjutkan untuk menghasilkan nilai 20.
Perbedaan ini dapat dirangkum sebagai berikut:
Pemilihan antara `return` dan `yield` harus disesuaikan dengan tujuan program. Jika sebuah fungsi hanya perlu menghasilkan satu hasil akhir, `return` biasanya sudah memadai. Jika fungsi perlu menghasilkan sejumlah nilai secara bertahap, `yield` dapat menjadi pilihan yang lebih tepat.
Berikut contoh generator yang menghasilkan bilangan dari nol sampai angka sebelum batas yang ditentukan:
def hitung_mundur(batas):
angka = batas
while angka > 0:
yield angka
angka -= 1
for nilai in hitung_mundur(5):
print(nilai)
Hasil program:
5
4
3
2
1
Fungsi `hitung_mundur()` menerima argumen `batas` yang menentukan angka awal. Variabel `angka` diisi dengan nilai tersebut. Selama nilainya lebih besar daripada nol, generator memberikan nilai melalui `yield`, kemudian mengurangi nilai variabel sebanyak satu.
Ketika fungsi dipanggil dengan argumen 5, generator menghasilkan angka 5, 4, 3, 2, dan 1. Setelah nilainya menjadi nol, kondisi `while` tidak lagi terpenuhi sehingga fungsi berakhir.
Contoh tersebut memperlihatkan bahwa generator dapat menggabungkan perulangan, kondisi, variabel, dan `yield`. Dengan demikian, pemrogram dapat menghasilkan urutan yang mengikuti aturan tertentu tanpa harus menyusun seluruh elemen dalam daftar.
Generator juga dapat menerima beberapa argumen dan menerapkan perhitungan yang lebih rumit. Misalnya, program dapat menghasilkan bilangan kelipatan tertentu, deret pangkat, atau nilai yang diperoleh dari hasil perhitungan sebelumnya.
Keuntungan pendekatan ini adalah aturan penghasilan nilai dapat ditulis dalam bentuk fungsi yang mudah dibaca. Keadaan yang diperlukan untuk melanjutkan proses, seperti nilai penghitung, tetap tersedia selama generator masih aktif.
Perhatikan contoh berikut:
def generator_buah():
yield "Apel"
yield "Jeruk"
yield "Mangga"
buah = generator_buah()
print(next(buah))
print(next(buah))
print(next(buah))
Hasil program:
Apel
Jeruk
Mangga
Pada pemanggilan pertama, generator menghasilkan teks `Apel`. Pemanggilan kedua menghasilkan `Jeruk`, sedangkan pemanggilan ketiga menghasilkan `Mangga`.
Perlu diperhatikan bahwa fungsi generator hanya menghasilkan objek generator ketika dipanggil. Isi fungsi tidak langsung dijalankan sampai selesai. Pelaksanaan dimulai ketika nilai diminta melalui `next()` atau mekanisme pengulangan lainnya.
Jika fungsi `next()` dipanggil kembali setelah seluruh nilai habis, Python akan menimbulkan pengecualian `StopIteration`. Hal ini menandakan bahwa tidak ada nilai tambahan yang tersedia.
Untuk menghindari pemanggilan manual yang berlebihan, program biasanya menggunakan perulangan `for`. Perulangan tersebut secara otomatis meminta nilai berikutnya dan berhenti ketika generator selesai.
Meskipun demikian, penggunaan `next()` tetap berguna ketika pemrogram ingin mengendalikan pengambilan nilai secara langsung. Contohnya adalah ketika hanya beberapa nilai pertama yang diperlukan atau ketika ingin mempelajari proses kerja generator secara lebih terperinci.
Berikut contoh programnya:
def pangkat_dua(batas):
angka = 0
while angka < batas:
yield 2 ** angka
angka += 1
for hasil in pangkat_dua(6):
print(hasil)
Hasil program:
1
2
4
8
16
32
Fungsi `pangkat_dua()` dimulai dari nilai penghitung nol. Pada setiap putaran, generator menghasilkan hasil perhitungan `2 ** angka`. Setelah itu, penghitung dinaikkan satu angka.
Ketika fungsi dipanggil dengan argumen 6, nilai penghitung yang diproses adalah 0, 1, 2, 3, 4, dan 5. Oleh karena itu, hasil yang diperoleh adalah 1, 2, 4, 8, 16, dan 32.
Contoh tersebut menunjukkan bahwa generator tidak terbatas pada nilai yang sudah tersedia dalam sebuah daftar. Generator dapat menghitung nilai ketika diperlukan, kemudian memberikan hasilnya secara berurutan.
Pendekatan semacam ini berguna ketika sebuah program perlu menghasilkan banyak nilai berdasarkan rumus tertentu. Daripada menyimpan semua hasil dalam daftar, program dapat menghasilkan setiap hasil pada saat dibutuhkan.
Bentuk umum generator expression adalah sebagai berikut:
(ekspresi for elemen in iterable)
Bagian `ekspresi` menentukan nilai yang akan dihasilkan untuk setiap elemen, sedangkan `iterable` merupakan sumber data yang akan diproses.
Perhatikan contoh berikut:
kuadrat = (angka ** 2 for angka in range(5))
for nilai in kuadrat:
print(nilai)
Hasil program:
0
1
4
9
16
Pada contoh tersebut, `range(5)` menyediakan angka 0 sampai 4. Setiap angka dipangkatkan dua, kemudian hasilnya diberikan oleh generator secara bertahap.
Generator expression menggunakan tanda kurung, sedangkan list comprehension menggunakan tanda kurung siku. Perbedaan tanda tersebut berkaitan dengan jenis objek yang dihasilkan.
Contoh list comprehension:
kuadrat_daftar = [angka ** 2 for angka in range(5)]
print(kuadrat_daftar)
Hasil program:
[0, 1, 4, 9, 16]
Pada contoh pertama, program menghasilkan objek generator. Pada contoh kedua, program langsung membentuk daftar yang berisi seluruh hasil perhitungan.
Perbedaan tersebut penting ketika menentukan pendekatan pengolahan data. Daftar sesuai digunakan ketika seluruh hasil perlu disimpan dan dapat diakses kembali. Generator expression sesuai digunakan ketika nilai akan diproses secara berurutan dan seluruh hasil tidak harus disimpan sekaligus.
Generator expression sangat bermanfaat untuk operasi sederhana yang dapat dinyatakan dalam satu ekspresi. Namun, jika proses membutuhkan banyak kondisi atau langkah perhitungan, fungsi generator biasanya lebih mudah dibaca dan dipelihara.
Untuk membuat iterator secara manual, pemrogram biasanya perlu mendefinisikan kelas, mengatur keadaan internal, menyediakan nilai berikutnya, dan menentukan kapan proses harus berhenti. Generator menyederhanakan pekerjaan tersebut dengan mengelola keadaan pelaksanaan secara otomatis.
Sebagai gambaran, iterator khusus dapat dibuat menggunakan kelas berikut:
class Deret:
def __init__(self, batas):
self.batas = batas
self.nilai = 0
def __iter__(self):
return self
def __next__(self):
if self.nilai < self.batas:
hasil = self.nilai
self.nilai += 1
return hasil
raise StopIteration
Kelas tersebut dapat menghasilkan bilangan mulai dari nol sampai satu angka sebelum batas yang ditentukan. Namun, untuk mendapatkan perilaku serupa, generator dapat ditulis lebih sederhana:
def deret_generator(batas):
nilai = 0
while nilai < batas:
yield nilai
nilai += 1
Kedua pendekatan tersebut dapat menghasilkan urutan nilai yang sama apabila digunakan dengan batas yang sama.
Perbedaannya terletak pada cara implementasi. Iterator berbasis kelas memberikan kendali langsung terhadap perilaku objek melalui metode khusus. Generator memungkinkan pemrogram menulis urutan proses secara alami menggunakan perulangan dan `yield`.
Dengan demikian, generator dapat dianggap sebagai cara praktis untuk membuat iterator. Pemrogram tidak harus memilih salah satunya secara mutlak, tetapi dapat menentukan pendekatan yang paling sesuai dengan kompleksitas kebutuhan program.
Generator menawarkan pendekatan yang berbeda karena nilai dapat dihasilkan ketika diperlukan. Program tidak harus menyimpan seluruh rangkaian hasil dalam sebuah daftar. Untuk proses yang hanya membutuhkan satu nilai pada suatu waktu, pendekatan ini dapat mengurangi penggunaan memori secara signifikan.
Misalnya, sebuah program perlu menghasilkan kuadrat dari angka 1 sampai 1.000.000. Dengan menggunakan list comprehension, program dapat membentuk daftar yang menyimpan seluruh hasil perhitungan.
kuadrat = [angka ** 2 for angka in range(1, 1000001)]
Daftar tersebut memuat satu juta nilai. Jika seluruh hasil memang diperlukan sekaligus, penggunaan daftar dapat menjadi pilihan yang sesuai.
Namun, apabila nilai hanya perlu dijumlahkan, generator expression dapat digunakan:
jumlah = sum(
angka ** 2
for angka in range(1, 1000001)
)
print(jumlah)
Hasil program:
333333833333500000
Dalam contoh tersebut, ekspresi generator menghasilkan setiap kuadrat untuk diproses oleh fungsi `sum()`. Program tidak perlu membentuk daftar berisi satu juta hasil terlebih dahulu.
Meskipun demikian, generator tidak selalu lebih cepat atau lebih baik daripada daftar dalam semua situasi. Daftar dapat lebih sesuai ketika hasil harus diakses berulang kali berdasarkan indeks atau digunakan dalam berbagai proses. Generator lebih sesuai ketika data dapat diproses secara berurutan dan tidak perlu disimpan seluruhnya.
Selain itu, generator yang membaca sumber data yang sudah berada di memori tidak otomatis menghilangkan kebutuhan memori sumber tersebut. Penghematan paling terasa ketika generator menghindari pembentukan kumpulan hasil tambahan yang besar.
Sebagai contoh, generator berikut menghasilkan bilangan genap mulai dari nol:
def bilangan_genap():
angka = 0
while True:
yield angka
angka += 2
for nilai in bilangan_genap():
if nilai > 10:
break
print(nilai)
Hasil program:
0
2
4
6
8
10
Perulangan `while True` membuat proses generator terus berulang. Setiap putaran menghasilkan bilangan genap melalui `yield`, kemudian menaikkan nilai penghitung sebesar dua.
Karena generator tersebut tidak memiliki kondisi akhir di dalam fungsinya, perulangan pemanggil perlu menentukan kapan proses dihentikan. Pada contoh tersebut, pernyataan `break` menghentikan pengulangan ketika nilai yang diperoleh lebih besar daripada 10.
Generator tak terbatas bermanfaat untuk menghasilkan nomor urut, deret bilangan, atau data yang terus tersedia sesuai permintaan. Namun, penggunaannya memerlukan pengendalian yang jelas. Tanpa kondisi penghentian atau pembatasan jumlah nilai, perulangan yang terus meminta nilai dapat berjalan tanpa akhir.
Prinsip ini menunjukkan bahwa generator bukan hanya digunakan untuk menghasilkan daftar nilai yang jumlahnya sudah diketahui. Generator juga dapat menjadi sumber nilai yang terus berlanjut selama program membutuhkannya.
Sebagai contoh, program dapat menghasilkan bilangan, menghitung kuadratnya, kemudian menjumlahkan seluruh hasil tersebut. Proses dapat dibagi menjadi beberapa fungsi agar setiap fungsi mempunyai tanggung jawab yang jelas.
def deret_angka(batas):
for angka in range(1, batas + 1):
yield angka
def kuadratkan(data):
for angka in data:
yield angka ** 2
hasil = kuadratkan(deret_angka(5))
print(sum(hasil))
Hasil program:
55
Fungsi `deret_angka()` menghasilkan angka 1 sampai 5. Fungsi `kuadratkan()` menerima data tersebut, mengambil setiap angka, kemudian menghasilkan kuadratnya.
Ketika fungsi `sum()` memproses hasil generator, nilai kuadrat yang dihasilkan adalah 1, 4, 9, 16, dan 25. Jumlah seluruh nilai tersebut adalah 55.
Contoh ini memperlihatkan bahwa proses pengolahan data dapat dibagi menjadi beberapa tahap. Fungsi pertama bertugas menghasilkan data, sedangkan fungsi kedua melakukan transformasi terhadap data tersebut. Fungsi `sum()` kemudian menggabungkan hasilnya menjadi satu nilai akhir.
Pendekatan seperti ini dapat diterapkan pada proses yang lebih kompleks. Sebuah generator dapat membaca data, generator lain dapat menyaring data berdasarkan kondisi tertentu, dan generator berikutnya dapat mengubah format atau menghitung nilai tertentu.
Penggunaan beberapa generator secara berurutan dapat membantu membuat program lebih modular. Setiap bagian dapat diuji dan dikembangkan secara terpisah tanpa harus menempatkan seluruh proses dalam satu fungsi yang panjang.
Misalnya, terdapat daftar nilai ujian. Program ingin mengambil nilai yang mencapai batas kelulusan, yaitu 75, kemudian menghitung jumlah nilai yang memenuhi kriteria tersebut.
def nilai_lulus(data, batas=75):
for nilai in data:
if nilai >= batas:
yield nilai
nilai_siswa = [60, 80, 70, 90, 75, 65, 85]
hasil_lulus = nilai_lulus(nilai_siswa)
for nilai in hasil_lulus:
print(nilai)
Hasil program:
80
90
75
85
Fungsi `nilai_lulus()` menerima kumpulan nilai dan batas kelulusan. Setiap nilai diperiksa melalui pernyataan `if`. Jika nilainya sama dengan atau lebih besar daripada batas, generator menghasilkan nilai tersebut. Nilai yang tidak memenuhi kriteria dilewati.
Pendekatan tersebut memungkinkan program mengambil data yang sesuai tanpa harus membentuk daftar hasil tambahan secara langsung.
Jika jumlah nilai yang memenuhi kriteria perlu dihitung, fungsi `sum()` tidak dapat langsung digunakan untuk menghitung banyaknya elemen karena fungsi tersebut menjumlahkan nilai numerik. Sebagai gantinya, fungsi `sum()` dapat digunakan pada ekspresi yang menghasilkan angka satu untuk setiap nilai yang memenuhi syarat.
Contohnya:
nilai_siswa = [60, 80, 70, 90, 75, 65, 85]
jumlah_lulus = sum(
1 for nilai in nilai_siswa if nilai >= 75
)
print("Jumlah siswa yang lulus:", jumlah_lulus)
Hasil program:
Jumlah siswa yang lulus: 4
Contoh ini menggunakan generator expression untuk menghasilkan angka 1 bagi setiap nilai yang memenuhi kriteria. Fungsi `sum()` kemudian menjumlahkan angka-angka tersebut sehingga diperoleh jumlah siswa yang lulus.
Perlu dipahami bahwa daftar nilai pada contoh tersebut tetap disimpan dalam memori. Generator digunakan untuk menghasilkan hasil penyaringan atau perhitungan secara bertahap. Jika data berasal dari sumber yang besar, pendekatan serupa dapat membantu menghindari pembuatan daftar hasil tambahan yang tidak diperlukan.
Kesalahan pertama adalah menganggap pemanggilan fungsi generator langsung menjalankan seluruh isi fungsi. Sebenarnya, pemanggilan fungsi generator menghasilkan objek generator terlebih dahulu. Isi fungsi mulai dijalankan ketika nilai diminta.
Kesalahan kedua adalah mencoba menggunakan kembali generator yang telah habis. Generator biasanya hanya dapat menghasilkan rangkaian nilainya satu kali dalam satu siklus pelaksanaan. Setelah seluruh nilai habis, perulangan berikutnya terhadap objek generator yang sama tidak menghasilkan nilai tambahan.
Perhatikan contoh berikut:
def angka():
yield 1
yield 2
yield 3
hasil = angka()
for nilai in hasil:
print(nilai)
for nilai in hasil:
print(nilai)
Perulangan pertama menampilkan angka 1, 2, dan 3. Perulangan kedua tidak menghasilkan keluaran karena generator telah habis.
Jika program membutuhkan rangkaian nilai yang sama kembali, objek generator baru perlu dibuat dengan memanggil fungsi `angka()` sekali lagi.
Kesalahan ketiga adalah menganggap generator selalu lebih efisien dalam segala hal. Generator dapat mengurangi kebutuhan memori ketika hasil diolah secara bertahap, tetapi generator juga mempunyai biaya pelaksanaan dan tidak menyediakan akses acak seperti daftar. Jika data perlu diakses berulang kali berdasarkan indeks, daftar mungkin menjadi pilihan yang lebih tepat.
Kesalahan keempat adalah membuat generator tak terbatas tanpa mekanisme penghentian pada bagian pemanggil. Generator yang terus menghasilkan nilai dapat menyebabkan perulangan berjalan tanpa akhir apabila program tidak membatasi jumlah data yang diambil.
Kesalahan kelima adalah tidak memperhatikan sumber data. Jika generator membaca data dari suatu sumber yang hanya dapat digunakan sekali, seperti aliran data tertentu, penggunaan ulang sumber tersebut mungkin memerlukan proses baru untuk membukanya atau membuatnya kembali.
Dengan memahami karakteristik tersebut, pemrogram dapat memilih generator secara tepat dan menghindari kesalahan yang berkaitan dengan keadaan, jumlah nilai, serta pengulangan proses.
Untuk transformasi sederhana terhadap elemen dalam iterable, generator expression dapat memberikan penulisan yang ringkas. Contohnya adalah menghasilkan kuadrat bilangan atau memfilter nilai berdasarkan kondisi tertentu.
Ketika seluruh hasil perlu disimpan dan digunakan kembali, daftar dapat menjadi pilihan yang lebih sesuai. Sebaliknya, ketika hasil cukup diproses satu per satu, generator dapat mengurangi kebutuhan penyimpanan hasil tambahan.
Pemrogram juga perlu memahami bahwa generator menyimpan keadaan pelaksanaannya. Variabel lokal, posisi perulangan, dan proses yang telah dijalankan dapat dilanjutkan ketika nilai berikutnya diminta. Pengetahuan ini membantu menjelaskan mengapa generator yang telah berjalan tidak otomatis kembali ke awal.
Selain itu, generator sebaiknya dirancang dengan aturan penghasilan nilai yang jelas. Jika generator berpotensi menghasilkan nilai tanpa batas, bagian program yang menggunakannya harus mempunyai kondisi penghentian atau batas jumlah data.
Pengujian juga diperlukan untuk memastikan bahwa generator menghasilkan nilai yang benar, berhenti pada kondisi yang diharapkan, serta menangani data kosong dengan baik. Untuk generator yang membaca data dari sumber eksternal, penanganan kesalahan dan pengelolaan sumber data perlu dipertimbangkan secara khusus.
Dengan memperhatikan hal-hal tersebut, generator dapat menjadi alat yang berguna dalam pengembangan program Python yang lebih modular, mudah dibaca, dan efisien dalam pengolahan data.
Berbeda dengan fungsi biasa yang menggunakan `return` untuk mengembalikan hasil dan mengakhiri pelaksanaan fungsi, generator mempertahankan keadaan pelaksanaannya selama proses belum selesai. Nilai dapat diambil menggunakan `next()` atau melalui perulangan `for` yang mengelola pengambilan nilai dan penghentian proses secara otomatis.
Python menyediakan dua pendekatan utama untuk membuat generator, yaitu fungsi generator dan generator expression. Fungsi generator sesuai untuk proses yang melibatkan beberapa langkah, kondisi, atau perulangan. Generator expression cocok untuk menghasilkan nilai melalui ekspresi yang lebih ringkas.
Generator juga berkaitan erat dengan iterator. Setiap generator merupakan iterator, tetapi iterator tidak selalu dibuat menggunakan generator. Generator menjadi cara praktis untuk membangun iterator tanpa harus menuliskan kelas dan metode khusus secara manual.
Dalam pengolahan data, generator dapat digunakan untuk menghasilkan bilangan, menghitung pangkat, menyaring nilai siswa, mengolah aliran data tak terbatas, serta menggabungkan beberapa tahap pemrosesan. Kemampuan menghasilkan nilai sesuai kebutuhan dapat mengurangi kebutuhan memori, khususnya ketika program tidak perlu menyimpan seluruh hasil sekaligus.
Meskipun demikian, generator bukan pengganti semua struktur data. Daftar tetap berguna ketika data perlu disimpan, diakses berulang kali, atau diambil berdasarkan indeks. Pemilihan pendekatan harus mempertimbangkan kebutuhan program, karakteristik sumber data, serta cara hasil akan digunakan.
Dengan memahami pengertian generator, peran `yield`, perbedaan dengan `return`, penggunaan generator expression, dan penerapannya dalam pengolahan data, pemrogram dapat mengembangkan program Python dengan pendekatan yang lebih terstruktur. Penguasaan konsep ini menjadi bekal penting untuk mempelajari pemrosesan data yang lebih lanjut serta membangun program yang memanfaatkan sumber daya secara tepat.
Generator menawarkan pendekatan berbeda. Alih-alih menghasilkan seluruh nilai sekaligus, generator dapat memberikan satu nilai, menghentikan sementara prosesnya, kemudian melanjutkan pekerjaan ketika nilai berikutnya diminta. Mekanisme ini memungkinkan program mengolah data secara bertahap dengan kebutuhan penyimpanan yang berpotensi lebih kecil.
Generator juga berkaitan erat dengan konsep iterator dalam Python. Iterator merupakan objek yang menyediakan nilai berikutnya ketika diminta, sedangkan generator merupakan salah satu cara praktis untuk membuat iterator. Melalui generator, pemrogram tidak perlu selalu membuat kelas khusus beserta metode pengambilan nilai secara manual. Cukup dengan menggunakan fungsi dan kata kunci `yield`, rangkaian nilai dapat dihasilkan melalui kode yang lebih ringkas.
Pemahaman tentang generator bermanfaat bagi siapa pun yang mempelajari Python, baik pada tingkat dasar maupun lanjutan. Konsep ini membantu menjelaskan cara kerja pengambilan nilai secara bertahap, penggunaan memori, pengolahan data berukuran besar, serta penyusunan beberapa proses pengolahan data secara berurutan. Oleh karena itu, pembahasan generator perlu mencakup pengertian, karakteristik, cara pembuatan, perbedaannya dengan fungsi biasa dan iterator, hingga penerapannya dalam program.
Pengertian Generator dalam Python
Generator adalah mekanisme dalam Python yang memungkinkan sebuah fungsi menghasilkan serangkaian nilai secara bertahap. Fungsi generator mengembalikan objek generator yang dapat digunakan untuk mengambil nilai satu per satu. Nilai berikutnya baru dihasilkan ketika program meminta kelanjutan proses tersebut.Berbeda dengan fungsi biasa yang umumnya menggunakan `return` untuk mengembalikan hasil dan mengakhiri pelaksanaan fungsi, generator menggunakan kata kunci `yield` untuk menghasilkan nilai sekaligus menangguhkan sementara pelaksanaan fungsi. Setelah sebuah nilai diberikan, generator mempertahankan keadaan pelaksanaannya sehingga proses dapat dilanjutkan dari posisi terakhir ketika nilai berikutnya diminta.
Misalnya, sebuah program perlu menghasilkan angka 1, 2, 3, 4, dan 5. Salah satu pendekatan adalah menyimpan semua angka tersebut dalam sebuah daftar. Pendekatan lain adalah menggunakan generator yang menghasilkan angka satu per satu sesuai kebutuhan.
Contoh fungsi generator dapat ditulis sebagai berikut:
def deret_angka():
yield 1
yield 2
yield 3
yield 4
yield 5
for angka in deret_angka():
print(angka)
Hasil program:
1
2
3
4
5
Pada contoh tersebut, fungsi `deret_angka()` menggunakan kata kunci `yield` untuk menghasilkan lima nilai. Setiap kali generator diminta melanjutkan proses, fungsi menghasilkan nilai berikutnya sesuai urutan pernyataan `yield`.
Perulangan `for` kemudian mengambil setiap nilai dari objek generator dan menampilkannya. Setelah seluruh nilai dihasilkan, proses pengulangan berakhir secara otomatis.
Contoh tersebut memperlihatkan bahwa generator dapat digunakan untuk menghasilkan rangkaian nilai tanpa harus membuat daftar terlebih dahulu. Walaupun contoh lima angka terlihat sederhana, prinsip yang sama dapat diterapkan pada proses pengolahan data yang lebih kompleks.
Mengenal Kata Kunci yield
Kata kunci `yield` merupakan bagian terpenting dalam pembuatan generator menggunakan fungsi. Kata kunci ini digunakan untuk menghasilkan sebuah nilai dan menangguhkan sementara pelaksanaan fungsi. Ketika generator diminta memberikan nilai berikutnya, pelaksanaan dilanjutkan dari posisi setelah `yield` terakhir yang dijalankan.Untuk memahami mekanisme tersebut, perhatikan contoh berikut:
def contoh_generator():
print("Proses dimulai")
yield 10
print("Proses dilanjutkan")
yield 20
print("Proses berakhir")
yield 30
hasil = contoh_generator()
print(next(hasil))
print(next(hasil))
print(next(hasil))
Hasil program:
Proses dimulai
10
Proses dilanjutkan
20
Proses berakhir
30
Ketika fungsi `contoh_generator()` dipanggil, Python tidak langsung menjalankan seluruh isi fungsi. Pemanggilan tersebut menghasilkan objek generator. Pelaksanaan isi fungsi baru dimulai ketika program meminta nilai, misalnya melalui `next()`.
Pada pemanggilan pertama, generator menjalankan perintah `print("Proses dimulai")`, kemudian menghasilkan nilai 10 melalui `yield`. Pelaksanaan fungsi berhenti sementara pada titik tersebut.
Ketika `next(hasil)` dipanggil kembali, fungsi melanjutkan proses dari posisi terakhir. Pernyataan yang menampilkan teks `Proses dilanjutkan` dijalankan, kemudian generator menghasilkan nilai 20. Pada pemanggilan ketiga, proses dilanjutkan kembali hingga menghasilkan nilai 30.
Contoh tersebut menunjukkan bahwa `yield` bukan sekadar perintah untuk memberikan hasil. Kata kunci ini juga memungkinkan generator mempertahankan keadaan pelaksanaannya, termasuk variabel lokal dan posisi proses, selama generator belum selesai.
Ketika generator mencapai akhir fungsi tanpa menghasilkan nilai tambahan, iterator generator menjadi habis. Pemanggilan `next()` berikutnya akan menimbulkan `StopIteration`, sedangkan perulangan `for` akan berhenti secara otomatis.
Perbedaan yield dan return
Kata kunci `yield` dan `return` sama-sama dapat memberikan nilai dari sebuah fungsi, tetapi keduanya memiliki perilaku yang berbeda. Perbedaan tersebut penting karena menentukan apakah pelaksanaan fungsi akan berakhir atau dapat dilanjutkan kembali.Kata kunci `return` digunakan untuk mengembalikan hasil dan mengakhiri pelaksanaan fungsi. Setelah pernyataan `return` dijalankan, fungsi biasa tidak melanjutkan perintah yang berada setelahnya dalam pemanggilan tersebut.
Sebaliknya, `yield` memberikan nilai sambil menangguhkan pelaksanaan fungsi generator. Generator dapat dilanjutkan kembali ketika program meminta nilai berikutnya.
Perhatikan contoh fungsi biasa berikut:
def fungsi_biasa():
return 10
return 20
print(fungsi_biasa())
Hasil program:
10
Fungsi tersebut hanya mengembalikan angka 10. Pernyataan `return 20` tidak dijalankan karena fungsi telah berakhir setelah pernyataan `return` pertama.
Bandingkan dengan contoh generator berikut:
def fungsi_generator():
yield 10
yield 20
for nilai in fungsi_generator():
print(nilai)
Hasil program:
10
20
Generator tersebut dapat menghasilkan kedua nilai karena `yield` tidak langsung mengakhiri fungsi. Pelaksanaan ditangguhkan setelah nilai 10 diberikan, kemudian dilanjutkan untuk menghasilkan nilai 20.
Perbedaan ini dapat dirangkum sebagai berikut:
Aspek |
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pemilihan antara `return` dan `yield` harus disesuaikan dengan tujuan program. Jika sebuah fungsi hanya perlu menghasilkan satu hasil akhir, `return` biasanya sudah memadai. Jika fungsi perlu menghasilkan sejumlah nilai secara bertahap, `yield` dapat menjadi pilihan yang lebih tepat.
Cara Membuat Generator Menggunakan Fungsi
Pembuatan generator menggunakan fungsi memiliki pola yang relatif sederhana. Pemrogram menuliskan fungsi dengan kata kunci `def`, menentukan aturan penghasilan nilai, kemudian menggunakan `yield` untuk memberikan nilai yang akan dihasilkan.Berikut contoh generator yang menghasilkan bilangan dari nol sampai angka sebelum batas yang ditentukan:
def hitung_mundur(batas):
angka = batas
while angka > 0:
yield angka
angka -= 1
for nilai in hitung_mundur(5):
print(nilai)
Hasil program:
5
4
3
2
1
Fungsi `hitung_mundur()` menerima argumen `batas` yang menentukan angka awal. Variabel `angka` diisi dengan nilai tersebut. Selama nilainya lebih besar daripada nol, generator memberikan nilai melalui `yield`, kemudian mengurangi nilai variabel sebanyak satu.
Ketika fungsi dipanggil dengan argumen 5, generator menghasilkan angka 5, 4, 3, 2, dan 1. Setelah nilainya menjadi nol, kondisi `while` tidak lagi terpenuhi sehingga fungsi berakhir.
Contoh tersebut memperlihatkan bahwa generator dapat menggabungkan perulangan, kondisi, variabel, dan `yield`. Dengan demikian, pemrogram dapat menghasilkan urutan yang mengikuti aturan tertentu tanpa harus menyusun seluruh elemen dalam daftar.
Generator juga dapat menerima beberapa argumen dan menerapkan perhitungan yang lebih rumit. Misalnya, program dapat menghasilkan bilangan kelipatan tertentu, deret pangkat, atau nilai yang diperoleh dari hasil perhitungan sebelumnya.
Keuntungan pendekatan ini adalah aturan penghasilan nilai dapat ditulis dalam bentuk fungsi yang mudah dibaca. Keadaan yang diperlukan untuk melanjutkan proses, seperti nilai penghitung, tetap tersedia selama generator masih aktif.
Mengambil Nilai Generator dengan Fungsi next()
Nilai dari generator dapat diambil satu per satu menggunakan fungsi bawaan `next()`. Fungsi ini meminta nilai berikutnya dari objek generator. Setiap pemanggilan akan melanjutkan pelaksanaan generator sampai nilai berikutnya dihasilkan atau generator selesai.Perhatikan contoh berikut:
def generator_buah():
yield "Apel"
yield "Jeruk"
yield "Mangga"
buah = generator_buah()
print(next(buah))
print(next(buah))
print(next(buah))
Hasil program:
Apel
Jeruk
Mangga
Pada pemanggilan pertama, generator menghasilkan teks `Apel`. Pemanggilan kedua menghasilkan `Jeruk`, sedangkan pemanggilan ketiga menghasilkan `Mangga`.
Perlu diperhatikan bahwa fungsi generator hanya menghasilkan objek generator ketika dipanggil. Isi fungsi tidak langsung dijalankan sampai selesai. Pelaksanaan dimulai ketika nilai diminta melalui `next()` atau mekanisme pengulangan lainnya.
Jika fungsi `next()` dipanggil kembali setelah seluruh nilai habis, Python akan menimbulkan pengecualian `StopIteration`. Hal ini menandakan bahwa tidak ada nilai tambahan yang tersedia.
Untuk menghindari pemanggilan manual yang berlebihan, program biasanya menggunakan perulangan `for`. Perulangan tersebut secara otomatis meminta nilai berikutnya dan berhenti ketika generator selesai.
Meskipun demikian, penggunaan `next()` tetap berguna ketika pemrogram ingin mengendalikan pengambilan nilai secara langsung. Contohnya adalah ketika hanya beberapa nilai pertama yang diperlukan atau ketika ingin mempelajari proses kerja generator secara lebih terperinci.
Membuat Generator untuk Menghasilkan Bilangan Berpangkat
Generator dapat digunakan untuk menghasilkan hasil perhitungan secara bertahap. Salah satu contoh yang mudah dipahami adalah menghasilkan pangkat dua dari bilangan tertentu.Berikut contoh programnya:
def pangkat_dua(batas):
angka = 0
while angka < batas:
yield 2 ** angka
angka += 1
for hasil in pangkat_dua(6):
print(hasil)
Hasil program:
1
2
4
8
16
32
Fungsi `pangkat_dua()` dimulai dari nilai penghitung nol. Pada setiap putaran, generator menghasilkan hasil perhitungan `2 ** angka`. Setelah itu, penghitung dinaikkan satu angka.
Ketika fungsi dipanggil dengan argumen 6, nilai penghitung yang diproses adalah 0, 1, 2, 3, 4, dan 5. Oleh karena itu, hasil yang diperoleh adalah 1, 2, 4, 8, 16, dan 32.
Contoh tersebut menunjukkan bahwa generator tidak terbatas pada nilai yang sudah tersedia dalam sebuah daftar. Generator dapat menghitung nilai ketika diperlukan, kemudian memberikan hasilnya secara berurutan.
Pendekatan semacam ini berguna ketika sebuah program perlu menghasilkan banyak nilai berdasarkan rumus tertentu. Daripada menyimpan semua hasil dalam daftar, program dapat menghasilkan setiap hasil pada saat dibutuhkan.
Generator Expression sebagai Cara yang Lebih Ringkas
Selain menggunakan fungsi generator, Python menyediakan generator expression. Generator expression merupakan cara ringkas untuk membuat objek generator menggunakan bentuk ekspresi yang menyerupai pemahaman daftar atau *list comprehension*.Bentuk umum generator expression adalah sebagai berikut:
(ekspresi for elemen in iterable)
Bagian `ekspresi` menentukan nilai yang akan dihasilkan untuk setiap elemen, sedangkan `iterable` merupakan sumber data yang akan diproses.
Perhatikan contoh berikut:
kuadrat = (angka ** 2 for angka in range(5))
for nilai in kuadrat:
print(nilai)
Hasil program:
0
1
4
9
16
Pada contoh tersebut, `range(5)` menyediakan angka 0 sampai 4. Setiap angka dipangkatkan dua, kemudian hasilnya diberikan oleh generator secara bertahap.
Generator expression menggunakan tanda kurung, sedangkan list comprehension menggunakan tanda kurung siku. Perbedaan tanda tersebut berkaitan dengan jenis objek yang dihasilkan.
Contoh list comprehension:
kuadrat_daftar = [angka ** 2 for angka in range(5)]
print(kuadrat_daftar)
Hasil program:
[0, 1, 4, 9, 16]
Pada contoh pertama, program menghasilkan objek generator. Pada contoh kedua, program langsung membentuk daftar yang berisi seluruh hasil perhitungan.
Perbedaan tersebut penting ketika menentukan pendekatan pengolahan data. Daftar sesuai digunakan ketika seluruh hasil perlu disimpan dan dapat diakses kembali. Generator expression sesuai digunakan ketika nilai akan diproses secara berurutan dan seluruh hasil tidak harus disimpan sekaligus.
Generator expression sangat bermanfaat untuk operasi sederhana yang dapat dinyatakan dalam satu ekspresi. Namun, jika proses membutuhkan banyak kondisi atau langkah perhitungan, fungsi generator biasanya lebih mudah dibaca dan dipelihara.
Perbedaan Generator dan Iterator
Generator dan iterator merupakan konsep yang saling berhubungan, tetapi tidak sepenuhnya sama. Iterator adalah objek yang mengikuti protokol iterator, yaitu menyediakan metode `__iter__()` dan `__next__()`. Generator merupakan salah satu jenis iterator yang dibuat menggunakan fungsi generator atau generator expression.Untuk membuat iterator secara manual, pemrogram biasanya perlu mendefinisikan kelas, mengatur keadaan internal, menyediakan nilai berikutnya, dan menentukan kapan proses harus berhenti. Generator menyederhanakan pekerjaan tersebut dengan mengelola keadaan pelaksanaan secara otomatis.
Sebagai gambaran, iterator khusus dapat dibuat menggunakan kelas berikut:
class Deret:
def __init__(self, batas):
self.batas = batas
self.nilai = 0
def __iter__(self):
return self
def __next__(self):
if self.nilai < self.batas:
hasil = self.nilai
self.nilai += 1
return hasil
raise StopIteration
Kelas tersebut dapat menghasilkan bilangan mulai dari nol sampai satu angka sebelum batas yang ditentukan. Namun, untuk mendapatkan perilaku serupa, generator dapat ditulis lebih sederhana:
def deret_generator(batas):
nilai = 0
while nilai < batas:
yield nilai
nilai += 1
Kedua pendekatan tersebut dapat menghasilkan urutan nilai yang sama apabila digunakan dengan batas yang sama.
Perbedaannya terletak pada cara implementasi. Iterator berbasis kelas memberikan kendali langsung terhadap perilaku objek melalui metode khusus. Generator memungkinkan pemrogram menulis urutan proses secara alami menggunakan perulangan dan `yield`.
Dengan demikian, generator dapat dianggap sebagai cara praktis untuk membuat iterator. Pemrogram tidak harus memilih salah satunya secara mutlak, tetapi dapat menentukan pendekatan yang paling sesuai dengan kompleksitas kebutuhan program.
Keunggulan Generator dalam Penggunaan Memori
Salah satu alasan generator banyak digunakan adalah kemampuannya menghasilkan nilai secara bertahap. Ketika sebuah program membentuk daftar yang berisi jutaan hasil perhitungan, seluruh hasil tersebut perlu disimpan dalam struktur data. Kebutuhan memori dapat meningkat seiring bertambahnya jumlah elemen.Generator menawarkan pendekatan yang berbeda karena nilai dapat dihasilkan ketika diperlukan. Program tidak harus menyimpan seluruh rangkaian hasil dalam sebuah daftar. Untuk proses yang hanya membutuhkan satu nilai pada suatu waktu, pendekatan ini dapat mengurangi penggunaan memori secara signifikan.
Misalnya, sebuah program perlu menghasilkan kuadrat dari angka 1 sampai 1.000.000. Dengan menggunakan list comprehension, program dapat membentuk daftar yang menyimpan seluruh hasil perhitungan.
kuadrat = [angka ** 2 for angka in range(1, 1000001)]
Daftar tersebut memuat satu juta nilai. Jika seluruh hasil memang diperlukan sekaligus, penggunaan daftar dapat menjadi pilihan yang sesuai.
Namun, apabila nilai hanya perlu dijumlahkan, generator expression dapat digunakan:
jumlah = sum(
angka ** 2
for angka in range(1, 1000001)
)
print(jumlah)
Hasil program:
333333833333500000
Dalam contoh tersebut, ekspresi generator menghasilkan setiap kuadrat untuk diproses oleh fungsi `sum()`. Program tidak perlu membentuk daftar berisi satu juta hasil terlebih dahulu.
Meskipun demikian, generator tidak selalu lebih cepat atau lebih baik daripada daftar dalam semua situasi. Daftar dapat lebih sesuai ketika hasil harus diakses berulang kali berdasarkan indeks atau digunakan dalam berbagai proses. Generator lebih sesuai ketika data dapat diproses secara berurutan dan tidak perlu disimpan seluruhnya.
Selain itu, generator yang membaca sumber data yang sudah berada di memori tidak otomatis menghilangkan kebutuhan memori sumber tersebut. Penghematan paling terasa ketika generator menghindari pembentukan kumpulan hasil tambahan yang besar.
Generator untuk Menghasilkan Aliran Data Tak Terbatas
Generator juga dapat digunakan untuk menghasilkan nilai tanpa batas akhir yang telah ditentukan. Aliran data semacam ini disebut aliran tak terbatas karena generator dapat terus memberikan nilai selama masih diminta.Sebagai contoh, generator berikut menghasilkan bilangan genap mulai dari nol:
def bilangan_genap():
angka = 0
while True:
yield angka
angka += 2
for nilai in bilangan_genap():
if nilai > 10:
break
print(nilai)
Hasil program:
0
2
4
6
8
10
Perulangan `while True` membuat proses generator terus berulang. Setiap putaran menghasilkan bilangan genap melalui `yield`, kemudian menaikkan nilai penghitung sebesar dua.
Karena generator tersebut tidak memiliki kondisi akhir di dalam fungsinya, perulangan pemanggil perlu menentukan kapan proses dihentikan. Pada contoh tersebut, pernyataan `break` menghentikan pengulangan ketika nilai yang diperoleh lebih besar daripada 10.
Generator tak terbatas bermanfaat untuk menghasilkan nomor urut, deret bilangan, atau data yang terus tersedia sesuai permintaan. Namun, penggunaannya memerlukan pengendalian yang jelas. Tanpa kondisi penghentian atau pembatasan jumlah nilai, perulangan yang terus meminta nilai dapat berjalan tanpa akhir.
Prinsip ini menunjukkan bahwa generator bukan hanya digunakan untuk menghasilkan daftar nilai yang jumlahnya sudah diketahui. Generator juga dapat menjadi sumber nilai yang terus berlanjut selama program membutuhkannya.
Menggabungkan Beberapa Generator dalam Pengolahan Data
Salah satu penggunaan generator yang menarik adalah menggabungkan beberapa fungsi generator untuk membentuk alur pengolahan data. Hasil dari satu generator dapat menjadi masukan bagi generator lain, sehingga setiap tahap dapat menjalankan tugas yang berbeda.Sebagai contoh, program dapat menghasilkan bilangan, menghitung kuadratnya, kemudian menjumlahkan seluruh hasil tersebut. Proses dapat dibagi menjadi beberapa fungsi agar setiap fungsi mempunyai tanggung jawab yang jelas.
def deret_angka(batas):
for angka in range(1, batas + 1):
yield angka
def kuadratkan(data):
for angka in data:
yield angka ** 2
hasil = kuadratkan(deret_angka(5))
print(sum(hasil))
Hasil program:
55
Fungsi `deret_angka()` menghasilkan angka 1 sampai 5. Fungsi `kuadratkan()` menerima data tersebut, mengambil setiap angka, kemudian menghasilkan kuadratnya.
Ketika fungsi `sum()` memproses hasil generator, nilai kuadrat yang dihasilkan adalah 1, 4, 9, 16, dan 25. Jumlah seluruh nilai tersebut adalah 55.
Contoh ini memperlihatkan bahwa proses pengolahan data dapat dibagi menjadi beberapa tahap. Fungsi pertama bertugas menghasilkan data, sedangkan fungsi kedua melakukan transformasi terhadap data tersebut. Fungsi `sum()` kemudian menggabungkan hasilnya menjadi satu nilai akhir.
Pendekatan seperti ini dapat diterapkan pada proses yang lebih kompleks. Sebuah generator dapat membaca data, generator lain dapat menyaring data berdasarkan kondisi tertentu, dan generator berikutnya dapat mengubah format atau menghitung nilai tertentu.
Penggunaan beberapa generator secara berurutan dapat membantu membuat program lebih modular. Setiap bagian dapat diuji dan dikembangkan secara terpisah tanpa harus menempatkan seluruh proses dalam satu fungsi yang panjang.
Penerapan Generator dalam Pengolahan Nilai Siswa
Generator dapat digunakan dalam berbagai kegiatan pengolahan data pendidikan. Salah satu contohnya adalah menghasilkan nilai yang memenuhi kriteria tertentu dari sekumpulan data nilai siswa.Misalnya, terdapat daftar nilai ujian. Program ingin mengambil nilai yang mencapai batas kelulusan, yaitu 75, kemudian menghitung jumlah nilai yang memenuhi kriteria tersebut.
def nilai_lulus(data, batas=75):
for nilai in data:
if nilai >= batas:
yield nilai
nilai_siswa = [60, 80, 70, 90, 75, 65, 85]
hasil_lulus = nilai_lulus(nilai_siswa)
for nilai in hasil_lulus:
print(nilai)
Hasil program:
80
90
75
85
Fungsi `nilai_lulus()` menerima kumpulan nilai dan batas kelulusan. Setiap nilai diperiksa melalui pernyataan `if`. Jika nilainya sama dengan atau lebih besar daripada batas, generator menghasilkan nilai tersebut. Nilai yang tidak memenuhi kriteria dilewati.
Pendekatan tersebut memungkinkan program mengambil data yang sesuai tanpa harus membentuk daftar hasil tambahan secara langsung.
Jika jumlah nilai yang memenuhi kriteria perlu dihitung, fungsi `sum()` tidak dapat langsung digunakan untuk menghitung banyaknya elemen karena fungsi tersebut menjumlahkan nilai numerik. Sebagai gantinya, fungsi `sum()` dapat digunakan pada ekspresi yang menghasilkan angka satu untuk setiap nilai yang memenuhi syarat.
Contohnya:
nilai_siswa = [60, 80, 70, 90, 75, 65, 85]
jumlah_lulus = sum(
1 for nilai in nilai_siswa if nilai >= 75
)
print("Jumlah siswa yang lulus:", jumlah_lulus)
Hasil program:
Jumlah siswa yang lulus: 4
Contoh ini menggunakan generator expression untuk menghasilkan angka 1 bagi setiap nilai yang memenuhi kriteria. Fungsi `sum()` kemudian menjumlahkan angka-angka tersebut sehingga diperoleh jumlah siswa yang lulus.
Perlu dipahami bahwa daftar nilai pada contoh tersebut tetap disimpan dalam memori. Generator digunakan untuk menghasilkan hasil penyaringan atau perhitungan secara bertahap. Jika data berasal dari sumber yang besar, pendekatan serupa dapat membantu menghindari pembuatan daftar hasil tambahan yang tidak diperlukan.
Kesalahan yang Perlu Dihindari ketika Menggunakan Generator
Meskipun generator memberikan banyak kemudahan, terdapat beberapa hal yang perlu diperhatikan agar penggunaannya tidak menimbulkan kesalahan.Kesalahan pertama adalah menganggap pemanggilan fungsi generator langsung menjalankan seluruh isi fungsi. Sebenarnya, pemanggilan fungsi generator menghasilkan objek generator terlebih dahulu. Isi fungsi mulai dijalankan ketika nilai diminta.
Kesalahan kedua adalah mencoba menggunakan kembali generator yang telah habis. Generator biasanya hanya dapat menghasilkan rangkaian nilainya satu kali dalam satu siklus pelaksanaan. Setelah seluruh nilai habis, perulangan berikutnya terhadap objek generator yang sama tidak menghasilkan nilai tambahan.
Perhatikan contoh berikut:
def angka():
yield 1
yield 2
yield 3
hasil = angka()
for nilai in hasil:
print(nilai)
for nilai in hasil:
print(nilai)
Perulangan pertama menampilkan angka 1, 2, dan 3. Perulangan kedua tidak menghasilkan keluaran karena generator telah habis.
Jika program membutuhkan rangkaian nilai yang sama kembali, objek generator baru perlu dibuat dengan memanggil fungsi `angka()` sekali lagi.
Kesalahan ketiga adalah menganggap generator selalu lebih efisien dalam segala hal. Generator dapat mengurangi kebutuhan memori ketika hasil diolah secara bertahap, tetapi generator juga mempunyai biaya pelaksanaan dan tidak menyediakan akses acak seperti daftar. Jika data perlu diakses berulang kali berdasarkan indeks, daftar mungkin menjadi pilihan yang lebih tepat.
Kesalahan keempat adalah membuat generator tak terbatas tanpa mekanisme penghentian pada bagian pemanggil. Generator yang terus menghasilkan nilai dapat menyebabkan perulangan berjalan tanpa akhir apabila program tidak membatasi jumlah data yang diambil.
Kesalahan kelima adalah tidak memperhatikan sumber data. Jika generator membaca data dari suatu sumber yang hanya dapat digunakan sekali, seperti aliran data tertentu, penggunaan ulang sumber tersebut mungkin memerlukan proses baru untuk membukanya atau membuatnya kembali.
Dengan memahami karakteristik tersebut, pemrogram dapat memilih generator secara tepat dan menghindari kesalahan yang berkaitan dengan keadaan, jumlah nilai, serta pengulangan proses.
Tips Menggunakan Generator secara Efektif
Agar generator memberikan manfaat yang optimal, penggunaannya perlu disesuaikan dengan kebutuhan program. Untuk menghasilkan rangkaian nilai melalui beberapa langkah perhitungan, fungsi generator biasanya menjadi pilihan yang jelas dan mudah dipahami.Untuk transformasi sederhana terhadap elemen dalam iterable, generator expression dapat memberikan penulisan yang ringkas. Contohnya adalah menghasilkan kuadrat bilangan atau memfilter nilai berdasarkan kondisi tertentu.
Ketika seluruh hasil perlu disimpan dan digunakan kembali, daftar dapat menjadi pilihan yang lebih sesuai. Sebaliknya, ketika hasil cukup diproses satu per satu, generator dapat mengurangi kebutuhan penyimpanan hasil tambahan.
Pemrogram juga perlu memahami bahwa generator menyimpan keadaan pelaksanaannya. Variabel lokal, posisi perulangan, dan proses yang telah dijalankan dapat dilanjutkan ketika nilai berikutnya diminta. Pengetahuan ini membantu menjelaskan mengapa generator yang telah berjalan tidak otomatis kembali ke awal.
Selain itu, generator sebaiknya dirancang dengan aturan penghasilan nilai yang jelas. Jika generator berpotensi menghasilkan nilai tanpa batas, bagian program yang menggunakannya harus mempunyai kondisi penghentian atau batas jumlah data.
Pengujian juga diperlukan untuk memastikan bahwa generator menghasilkan nilai yang benar, berhenti pada kondisi yang diharapkan, serta menangani data kosong dengan baik. Untuk generator yang membaca data dari sumber eksternal, penanganan kesalahan dan pengelolaan sumber data perlu dipertimbangkan secara khusus.
Dengan memperhatikan hal-hal tersebut, generator dapat menjadi alat yang berguna dalam pengembangan program Python yang lebih modular, mudah dibaca, dan efisien dalam pengolahan data.
Kesimpulan
Generator merupakan salah satu fitur penting dalam Python yang memungkinkan fungsi menghasilkan nilai secara bertahap. Melalui kata kunci `yield`, sebuah fungsi dapat memberikan nilai sekaligus menangguhkan pelaksanaan sementara, kemudian melanjutkan prosesnya ketika nilai berikutnya diminta.Berbeda dengan fungsi biasa yang menggunakan `return` untuk mengembalikan hasil dan mengakhiri pelaksanaan fungsi, generator mempertahankan keadaan pelaksanaannya selama proses belum selesai. Nilai dapat diambil menggunakan `next()` atau melalui perulangan `for` yang mengelola pengambilan nilai dan penghentian proses secara otomatis.
Python menyediakan dua pendekatan utama untuk membuat generator, yaitu fungsi generator dan generator expression. Fungsi generator sesuai untuk proses yang melibatkan beberapa langkah, kondisi, atau perulangan. Generator expression cocok untuk menghasilkan nilai melalui ekspresi yang lebih ringkas.
Generator juga berkaitan erat dengan iterator. Setiap generator merupakan iterator, tetapi iterator tidak selalu dibuat menggunakan generator. Generator menjadi cara praktis untuk membangun iterator tanpa harus menuliskan kelas dan metode khusus secara manual.
Dalam pengolahan data, generator dapat digunakan untuk menghasilkan bilangan, menghitung pangkat, menyaring nilai siswa, mengolah aliran data tak terbatas, serta menggabungkan beberapa tahap pemrosesan. Kemampuan menghasilkan nilai sesuai kebutuhan dapat mengurangi kebutuhan memori, khususnya ketika program tidak perlu menyimpan seluruh hasil sekaligus.
Meskipun demikian, generator bukan pengganti semua struktur data. Daftar tetap berguna ketika data perlu disimpan, diakses berulang kali, atau diambil berdasarkan indeks. Pemilihan pendekatan harus mempertimbangkan kebutuhan program, karakteristik sumber data, serta cara hasil akan digunakan.
Dengan memahami pengertian generator, peran `yield`, perbedaan dengan `return`, penggunaan generator expression, dan penerapannya dalam pengolahan data, pemrogram dapat mengembangkan program Python dengan pendekatan yang lebih terstruktur. Penguasaan konsep ini menjadi bekal penting untuk mempelajari pemrosesan data yang lebih lanjut serta membangun program yang memanfaatkan sumber daya secara tepat.
Artikel ini akan dibaca oleh: Farra Audia Sholeha, Fatma Dian Ferrari, Febrian Restu Andhika, Firza Tegar Febrian, dan Gadis Lolalita.
10 komentar untuk "Mengenal Generator dalam Python"
Hubungi admin melalui Wa : +62-896-2414-6106
Respon komentar 7 x 24 jam, mohon bersabar jika komentar tidak langsung dipublikasi atau mendapatkan balasan secara langsung.
Bantu admin meningkatkan kualitas blog dengan melaporkan berbagai permasalahan seperti typo, link bermasalah, dan lain sebagainya melalui kolom komentar.
- Ikatlah Ilmu dengan Memostingkannya -
Baru paham sekarang ternyata analisis teknikal itu lebih ke permainan bandar.
BalasHapusKlo admin sendiri pke aplikasi sekuritasnya apa?
BalasHapusSaya pakenya stockbit, lebih santai aja pakenya dari dulu, itu juga dapatnya dari rekomendasi teman yang udah pernah invest saham duluan.
HapusSaran aja nih, ketimbang lu invest saham cuma 100K, mending lu sekarang ningkatin earning powe aja dulu, soalnya duit 100k klo lo invest mentok-mentok dapetnya paling cuma serebu perak, dan itu lu harus nungguin setahun. Masih lebih untung tukang parkir.
BalasHapusiya gue sepakat nih, earning power itu adalah kemampuan untuk menghasilkan uang oleh seseorang dalam periode waktu tertentu, biasanya bulanan, dan sifatnya adalah penghasilan yang dilakukan secara aktif. Jadi kalo kalian udah pernah punya modal, sekitar 1juta atau 10juta, daeipada saham, mending modal itu digunakan untuk pelatihan yang dapat menambah softskill kita dalam dunia kerja, atau digunakan untuk membeli alat seperti laptop yang dapat digunakan untuk menunjang kinerja dan produktifitas kita. Klo produktifitas meningkat, atau kemampuan kerja meningkat, otomatis uang yang dapat dihasilkan juga meningkat.
HapusKlo penghasilan meningkat, otomatis tabungan juga meningkat, klo tabungan meningkat, maka modal untuk investasi saham juga jadi lebih besar.
Klo modal awal yang di pake buat investasi awal sudah besar, maka otomatis hasil yang didapstkan juga pasti besar.
Sepakat juga nih, tapi jangan langsung serakah diawal investasi, selalu pahami setiap tahapan untuk menghindari kehilangan dana dalam jumlah besar juga.
BalasHapusBaru tau ada yang namanya saham syariah, emg itu isinya pasti halal?
BalasHapusWaulahuallam, setidaknya sudah berikhtiar mencari yang paling baik.
HapusDi sini ada yang beli saham GOTO, kemaren sempat beli, sekarang malah nyesel, harganya langsung turun separoh.
BalasHapusGimana ga turun, isinya utang semua, itu nilai sahamnya baru bisa naik, klo utangnya udah beres semua, atau udah masuk kategori wajar.
Hapus