Generator - python


 

Generator


Pada artikel ini, kita akan belajar langkah membuat iterasi memakai generator, apakah bedanya generator dengan iterator dan peranan, dan kenapa kita harus memakai generator.


Pengertian Generator


Ada beberapa hal yang terlalu berlebih (overhead) di saat membuat iterator di Python. Pertama, kita harus membuat kelas yang memakai sistem __iter__() dan __next__(). Selanjutnya kita harus juga jaga state dari poin, dan harus menghidupkan StopIteration di saat tidak lagi ada poin yang ada.


Ini cukup panjang dan sulit. Dalam masalah ini, untuk menghindar hal itu, kita dapat memakai generator. Generator di Python ialah langkah simpel membuat iterator. Semua overhead yang kita sebut di atas, akan diatasi secara automatis oleh generator. Secara singkat, generator ialah peranan yang kembalikan sebuah object iterator yang kepadanya dapat kita kerjakan iterasi (satu nilai per satu waktu).


Cara Membuat Generator di Python


Cukup mudah untuk membikin generator di Python. Serupa dengan membuat peranan biasa. Namun, kita gantikan pengakuan return dengan yield. Peranan yang mempunyai minimum satu yield (peranan dapat berisi lebih satu yield atau return), bisa menjadi peranan generator. yield atau return sama - sama berperan kembalikan satu nilai dari sebuah peranan.


Ketidaksamaan return dan yield ialah, return akan hentikan (terminasi) peranan keseluruhannya, sementara yield cuman akan hentikan sementara (pause) peranan dan simpan semua state faktor yang untuk nanti dapat diteruskan datang dari state itu.


Perbedaan Fungsi Generator dan Fungsi Biasa


Berikut adalah perbedaan fungsi generator dengan fungsi biasa:


Peranan generator berisi satu ataupun lebih pengakuan yield

Di saat diundang, peranan generator akan kembalikan object iterator, tetapi tidak langsung dilakukan.

Sistem __iter__() dan __next__() telah diterapkan secara automatis . Maka kita langsung bisa lakukan iterasi dengan peranan next().

Sekali peranan menjumpai yield, peranan akan pause dan kendalian ditransfer kembali lagi ke pemanggil.

Faktor lokal dan state-nya dikenang untuk panggilan seterusnya.

Paling akhir, di saat peranan diterminasi (disetop total), StopIteration diundang secara automatis.


Berikut adalah contoh generator dengan beberapa pernyataan yield


script.py

IPython Shell


Powered by DataCamp


Seterusnya, hasilnya dapat digerakkan pada model interaktif sebagai berikut:


>>> # my_gen() kembalikan object iterator, tetapi tidak langsung menyelesaikannya

>>> a = my_gen()


>>> # Kita dapat lakukan iterasi pertama memakai next()

>>> next(a)

This is printed first

1

>>> # Sekali peranan mendapati yield, peranan akan dipause

>>> # dan kendalian dibalikkan ke pemanggil

>>> # Faktor lokal dan state-nya akan dikenang untuk panggilan seterusnya

>>> next(a)

This is printed second

2


>>> next(a)

This is printed at last

3


>>> Paling akhir, peranan diterminasi, StopIterasi automatis dibangkitkan

>>> next(a)

Traceback (most recent call last):

...

StopIteration


Salah satunya hal yang penting jadi perhatian untuk contoh di atas ialah, nilai dari faktor n masih tetap dikenang pada setiap panggilan peranan.


Berlainan dengan peranan normal, faktor lokal tidak dihancurkan di saat pengakuan yield. Disamping itu, object generator cuman dapat diiterasi untuk sekali saja. Untuk mengulang-ulang kembali proses, kita harus membuat generator lain memakai pengakuan misalnya a = my_gen().


Kita bisa juga memakai generator dalam loop for langsung. Ini karena loop for menggunakan iterator dan lakukan iterasi kepadanya memakai peranan next(). StopIteration automatis dilaksanakan di akhir iterasi.


script.py

IPython Shell


Powered by DataCamp


Di saat contoh di atas digerakkan, hasilnya akan terlihat sebagai berikut:


This is printed first

1

This is printed second

2

This is printed at last

3


Generator Menggunakan Loop


Beberapa contoh di atas jarang-jarang digunakan. Kita pelajarinya cuman untuk tahu teknisnya apa yang sebetulnya terjadi pada generator.


Biasanya, peranan generator diaplikasikan pada loop yang mempunyai keadaan terminasi (pemberhentian) yang tepat.


Silahkan kita bikin contoh generator yang berperan mengubah sebuah string.



script.py

IPython Shell


Powered by DataCamp


Pada contoh di atas, kita memakai peranan range() untuk memperoleh index secara kebalik yang dipakai dalam loop for.


Peranan generator semacam itu bukan hanya berlaku untuk string, tetapi juga untuk iterable yang lain seperti daftar, tuple, dan lain - lain.


Generator Expression


Generator simpel dapat dibikin dengan memakai generator expression. Dengan generator expression ini, pembikinan generator jadi gampang. Serupa dengan peranan lambda yang membuat peranan anonim, generator expression membuat suatu peranan generator anonim.


Sintaks dari generator expression serupa dengan daftar comprehension. Namun pertanda kurung [ ] diganti dengan pertanda kurung ( ). Ketidaksamaan khusus di antara daftar comprehension dengan generator expression ialah, daftar comprehension langsung hasilkan keseluruhnya anggota daftar, sedang generator expression hasilkannya satu poin per satu waktu.


Type seperti generator expression ini kerap disebutkan type lazy (malas), hanya karena menghasilkan poin di saat disuruh. Perihal ini pula yang mengakibatkan generator expression lebih irit memory daripada daftar comprehension.


script.py

IPython Shell


Powered by DataCamp


Kita dapat saksikan di atas, jika generator expression tidak langsung menghasilkan hasil keseluruhannya. Generator expression ini cuman kembalikan poin jika disuruh.


script.py

IPython Shell


Powered by DataCamp


Generator expression bisa juga dipakai sebagai argument peranan. Oleh karenanya, pertanda kurungnya dapat di hilangkan. Misalkan pada peranan sum() dan max() sebagai berikut:


>>> my_list = [1, 3, 6, 10]

>>> sum(x**2 for x in my_list)

146

>>> max(x**2 for x in my_list)

100


Argumen Pemakaian Generator


Ada banyak hal sebagai argumen pemakaian generator, yakni seperti berikut:


1. Gampang diaplikasikan


Generator dapat diaplikasikan lebih gampang dan singkat dibanding dengan kelas iterator. Berikut contoh pemakaian kelas iterator untuk hasilkan deret bilangan pangkat 2 dari 0 sampai yang bilangan ditetapkan.


class PowTwo:

def __init__(self, max=0):

self.max = max


def __iter__(self):

self.n = 0

return self


def __next__(self):

if self.n > self.max:

raise StopIteration


result = 2 ** self.n

self.n += 1

return result


Dan berikut hasilnya sama dengan memakai peranan generator.


def PowTwoGen(max = 0):

n = 0

while n < max:

yield 2 ** n

n += 1


Dari contoh di atas, kelihatan jika pemakaian generator lebih gampang dan singkat dibanding iterator.


2. Lebih Irit Memory


Peranan biasa yang dibikin untuk hasilkan sequence, akan simpan keseluruhnya sequence saat sebelum kembalikan hasilnya. Ini akan habiskan memory jika jumlah poinnya besar sekali. Saat itu, generator lebih irit memory hanya karena menghasilkan poin satu-satu yakni cuman saat diundang.


3. Merepresentasikan Stream Tidak Berhingga (Infinite Stream)


Generator ialah langkah yang terbagus untuk sebagai wakil saluran data yang tidak berhingga. Stream (saluran) data yang tidak berhingga, tidak dapat diletakkan dalam memory, hingga pas memakai generator. Berikut contoh untuk menghidupkan semua bilangan genap yang ada (minimal secara teoritis saja)


def all_even():

n = 0

while True:

yield n

n += 2


4. Pipelining Generator


Pipeline ialah jadikan input dari sebuah proses jadi dari proses operasi lainnya. Generator dapat dipakai untuk pipeline dari rangkaian operasi. Ini semakin lebih terang jika digambarkan dengan contoh.


Anggaplah kita memiliki sebuah file log dari rantai makanan cepat sajian populer. File log ini mempunyai sebuah kolom (kolom keempat) yang menulis jumlah pizza yang terjual tiap jam dan kita ingin menjumlahkannya untuk memperoleh jumlah pizza yang terjual dalam lima tahun.


Kita simpulkan jika semuanya yang kosong di kolom ke 4 sebagai 'N/A'. Karena itu, generator yang dapat diaplikasikan untuk ini ialah sebagai berikut.


with open('penjualan.log') as file:

pizza_col = (line[3] for line in file)

per_jam = (int(x) for x in pizza_col if x != 'N/A')

print("Keseluruhan pizza terjual = ", sum(per_jam))


Posting Komentar

Lebih baru Lebih lama

نموذج الاتصال