Iterators

Iterator adalah objek yang berisi sejumlah nilai yang dapat dihitung.

Iterator adalah objek yang dapat diiterasi, artinya Anda dapat menelusuri semua nilai.

Secara teknis, dalam Python, iterator adalah objek yang mengimplementasikan protokol iterator, yang terdiri dari metode __iter__() dan __next__().

Iterator vs Iterable

List, tuple, dictionary, dan set semuanya merupakan objek yang dapat diiterasi. Objek-objek ini merupakan kontainer yang dapat diiterasi, tempat Anda dapat memperoleh iterator.

Semua objek ini memiliki metode iter() yang digunakan untuk mendapatkan iterator:

# Return an iterator from a tuple, and print each value:

mytuple = ("apple", "banana", "cherry")
myit = iter(mytuple)

print(next(myit)) # apple
print(next(myit)) # banana
print(next(myit)) # cherry

Bahkan string adalah objek yang dapat diulang, dan dapat mengembalikan sebuah iterator:

# Strings are also iterable objects, containing a sequence of characters:

mystr = "banana"
myit = iter(mystr)

print(next(myit))
print(next(myit))
print(next(myit))
print(next(myit))
print(next(myit))
print(next(myit))

Looping Through an Iterator

Kita juga dapat menggunakan for loop untuk mengulang melalui objek yang dapat diulang:

# Iterate the values of a tuple:
mytuple = ("apple", "banana", "cherry")

for x in mytuple:
  print(x)


# Iterate the characters of a string:
mystr = "banana"

for x in mystr:
  print(x)

Perulangan for sebenarnya membuat objek iterator dan mengeksekusi metode next() untuk setiap perulangan.

Create an Iterator

Untuk membuat objek/kelas sebagai iterator, Anda harus mengimplementasikan metode __iter__() dan __next__() ke objek Anda.

Seperti yang telah Anda pelajari di bab Kelas/Objek Python, semua kelas memiliki fungsi yang disebut __init__(), yang memungkinkan Anda melakukan inisialisasi saat objek sedang dibuat.

Metode __iter__() berfungsi serupa, Anda dapat melakukan operasi (inisialisasi, dll.), tetapi harus selalu mengembalikan objek iterator itu sendiri.

Metode __next__() juga memungkinkan Anda melakukan operasi, dan harus mengembalikan item berikutnya dalam urutan tersebut.

Buat iterator yang mengembalikan angka, dimulai dengan 1, dan setiap urutan akan bertambah satu (mengembalikan 1,2,3,4,5, dst.):

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self

  def __next__(self):
    x = self.a
    self.a += 1
    return x

myclass = MyNumbers()
myiter = iter(myclass)

print(next(myiter)) #1
print(next(myiter)) # 2
print(next(myiter)) # 3
print(next(myiter)) # 4
print(next(myiter)) # 5

StopIteration

Contoh di atas akan terus berlanjut selamanya jika Anda memiliki cukup pernyataan next(), atau jika digunakan dalam for loop.

Untuk mencegah iterasi berlangsung selamanya, kita dapat menggunakan pernyataan StopIteration.

Dalam metode __next__(), kita dapat menambahkan kondisi terminasi untuk memunculkan kesalahan jika iterasi dilakukan beberapa kali:

# Stop after 20 iterations:

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self

  def __next__(self):
    if self.a <= 20:
      x = self.a
      self.a += 1
      return x
    else:
      raise StopIteration

myclass = MyNumbers()
myiter = iter(myclass)

for x in myiter:
  print(x)