Iterator

Iterator adalah objek yang padanya bisa dilakukan iterasi. Di  tutorial ini, kita akan mempelajari bagaimana cara kerja iterator dan cara membuat iterator kita sendiri menggunakan metode __iter__ dan __next__.


Tabel Konten:

  • Pengertian Iterator
  • Iterasi Menggunakan Iterator di Python
  • Bagaimana Loop Bekerja?
  • Membangun Iterator Sendiri
  • Iterator Tak Berhingga (Infinite Iterator)
  •  


    Pengertian Iterator

    Iterator di Python ada di mana – mana. Iterator ini  sebenarnya sudah diterapkan di dalam looping for, list comprehension, generator, dan lain – lain, hanya saja tidak tampak secara langsung.

    Iterator di Python sederhananya hanyalah suatu objek yang padanya dapat dilakukan iterasi atau looping. Objek akan mengembalikan data, satu data per satu waktu.

    Secara teknis, Objek iterator di Python harus menerapkan dua metode, yaitu __iter__() dan __next__(), yang disebut dengan protokol iterator.

    Suatu objek dikatakan iterable jika dari objek tersebut bisa kita buat iterator. Sebagian besar objek di Python seperti list, tuple, string, dan lain-lain adalah iterable.

    Fungsi iter() (fungsi yang memanggil metode __iter__()) akan mengembalikan iterator dari iterable yang menjadi argumennya.


    Iterasi Menggunakan Iterator di Python

    Kita menggunakan fungsi next() untuk melakukan iterasi pada semua item di iterator. Pada saat iterasi mencapai item terakhir dan tidak ada lagi data untuk dikembalikan, maka fungsi ini akan memunculkan StopIteration. Berikut adalah contohnya.

      # mendefinisikan list my_list = [4, 7, 0, 3] # membuat iterator dengan iter() my_iter = iter(my_list) # iterasi pada my_iter menggunakan next() # print 4 print(next(my_iter)) # print 7 print(next(my_iter)) # next(obj) sama dengan obj.__next__() # print 0 print(my_iter.__next__()) # print 3 print(my_iter.__next__()) # Berikut ini akan memunculkan error karena item sudah habis next(my_iter)

    Cara yang lebih bagus untuk melakukan iterasi pada iterator adalah dengan menggunakan loop for. Misalnya adalah seperti berikut:

    >>> for item in my_list
           print(item)
    
    4
    7
    0
    3

    Bagaimana Loop Bekerja?

    Seperti kita lihat pada contoh diatas, loop for bisa melakukan iterasi otomatis pada list.

    Seperti kita ketahui, loop for bisa melakukan iterasi pada iterable. Mari kita lihat lebih dekat bagaimana loop for diimplementasikan pada Python.

    for item in iterable:
        # proses item

    Di belakang layar, implementasi dari for di atas adalah sebagai berikut:

    # membuat iterator dari iterable
    iter_obj = iter(iterable)
    
    # loop infinite
    while True:
        try:
            # memanggil item selanjutnya
            item = next(iter_obj)
            # lakukan sesuatu pada item
        except StopIteration:
            # jika muncul StopIteration, keluar dari loop
            break

    Jadi, secara internal, loop for menciptakan objek iterator, iter_obj dengan memanggil fungsi iter().

    Loop for ini sebenarnya adalah sebuah loop while infinite (tak berhingga).

    Di dalam loop, fungsi next() akan dipanggil untuk mendapatkan item berikutnya dan body dari loop for akan dieksekusi menggunakan nilai item bersangkutan. Setelah semua item habis, StopIteration akan dimunculkan dan ini menandai akhir dari loop.


    Membangun Iterator Sendiri

    Membangun iterator dari dasar adalah hal yang mudah. Kita hanya perlu menerapkan metode __iter__() dan __next__().

    Metode __iter__() akan mengembalikan objek iterator. Bila diperlukan, beberapa pengaturan awal bisa dilakukan.

    Metode __next__() akan mengembalikan item selanjutnya yang ada di dalam sequence. Saat sudah mencapai item terakhir, maka pemanggilan berikutnya akan menghasilkan StopIteration.

    Berikut contoh program yang menampilkan pangkat 2 dari bilangan setiap kali iterasi. Eksponennya mulai dari nol sampai bilangan yang diset oleh user.

    class PowTwo: """Kelas yang mengimplementasikan iterator pangkat dua""" def __init__(self, max = 0): self.max = max def __iter__(self): self.n = 0 return self def __next__(self): if self.n <= self.max: result = 2 ** self.n self.n += 1 return result else: raise StopIteration

    Selanjutnya kita dapat membuat iterator dan melakukan iterasi seperti berikut

    >>> a = PowTwo(4)
    >>> i = iter(a)
    >>> next(i)
    1
    >>> next(i)
    2
    >>> next(i)
    4
    >>> next(i)
    8
    >>> next(i)
    16
    >>> next(i)
    Traceback (most recent call last):
    ...
    StopIteration

    Kita juga bisa melakukan iterasi menggunakan loop for pada iterator yang sudah kita buat.

    >>> for i in PowTwo(5):
            print(i)
    
    1
    2
    4
    8
    16
    32

    Iterator Tak Berhingga (Infinite Iterator)

    Kadangkala kita memerlukan iterator yang itemnya tidak akan habis. Tapi kita harus hati – hati untuk menangani iterator seperti ini.

    Berikut ini akan ditunjukkan contoh dari iterator tak berhingga.

    Fungsi built-in iter() dapat dipanggil menggunakan dua argumen, di mana argumen pertama adalah objek callable (sebuah fungsi) dan yang kedua adalah sentinel/penentu. Iterator memanggil fungsi ini sampai nilai yang dikembalikan sama dengan nilai sentinel.

    >>> int()
    0
    >>> inf = iter(int, 1)
    >>> next(inf)
    0
    >>> next(inf)
    0

    Kita bisa lihat bahwa fungsi int() tanpa argumen akan selalu mengembalikan nilai 0. Oleh sebab itu, saat fungsi int() dilewatkan ke iter(int, 1), akan dikembalikan iterator yang memanggil fungsi int() terus menerus sampai nilainya sama dengan sentinel 1. Dan hal ini,nilai 1 tidak akan pernah terjadi, sehingga yang didapat adalah iterator tak berhingga.

    Kita juga bisa membuat iterator tak berhingga kita sendiri. Secara teori, iterator berikut ini akan mengembalikan semua bilangan ganjil.

    class InfIter: """Infinite iterator yang mengembalikan semua bilangan ganjil""" def __iter__(self): self.num = 1 return self def __next__(self): num = self.num self.num += 2 return num

    Contoh penggunaannya adalah seperti berikut:

    >>> a = iter(InfIter())
    >>> next(a)
    1
    >>> next(a)
    3
    >>> next(a)
    5
    >>> next(a)
    7

    dan begitu selanjutnya…

    Kita perlu hati – hati untuk memasukkan kondisi terminasi untuk menghentikan iterasi pada iterator tak berhingga ini. Hal ini mirip dengan loop menggunakan while.

    Keuntungan dari penggunaan iterator adalah bisa menghemat penggunaan memori. Seperti pada contoh di atas, kita bisa mendapatkan semua bilangan ganjil tanpa harus menyimpan semua bilangan di dalam memori. Secara teori, kita bisa menyimpan item tak berhingga pada memori yang terbatas.

    Selain itu, iterator membuat kode terlihat lebih rapi dan bagus.

    Ada cara lain yang lebih mudah untuk membuat iterator di Python, yaitu dengan generator menggunakan yield.