Mekanisme Loop
Pada materi sebelumnya, kita telah mempelajari bahwa iterable, iterator, dan generator merupakan bagian penting dari mekanisme iterasi di Python.
Perulangan for yang terlihat sederhana ternyata memiliki mekanisme internal yang cukup menarik. Python menggunakan iterator untuk mengambil nilai dari sebuah iterable secara bertahap.
Memahami mekanisme ini membantu kita memahami bagaimana for, iter(), next(), dan StopIteration saling berhubungan.
Cara Kerja for Loop
Ketika kita menggunakan for terhadap sebuah iterable, Python perlu mendapatkan iterator dari object tersebut.
Secara konseptual, prosesnya dapat digambarkan:
Iterable
↓
iter()
↓
Iterator
↓
next()
↓
Nilai berikutnya
↓
next()
↓
Nilai berikutnya
↓
...
↓
StopIteration
↓
Loop selesai
Misalnya:
numbers = [1, 2, 3]
for number in numbers:
print(number)
Python menangani proses iterasi tersebut di belakang layar.
iter() dan __iter__()
Python menyediakan fungsi bawaan iter() untuk mendapatkan iterator dari sebuah iterable.
Contohnya:
numbers = [1, 2, 3]
iterator = iter(numbers)
print(iterator)
iter(numbers) menghasilkan sebuah iterator yang dapat digunakan untuk mengambil elemen secara bertahap.
Secara konsep:
list
↓
iter()
↓
iterator
Pada level object, mekanisme tersebut berkaitan dengan special method:
__iter__()
Method __iter__() digunakan untuk menyediakan iterator dari sebuah object.
next() dan __next__()
Setelah mendapatkan iterator, kita dapat mengambil nilai berikutnya menggunakan fungsi next().
Contohnya:
numbers = [1, 2, 3]
iterator = iter(numbers)
print(next(iterator))
print(next(iterator))
print(next(iterator))
Output:
1
2
3
Setiap pemanggilan next() mengambil nilai berikutnya dari iterator.
Secara konsep:
next(iterator)
↓
1
next(iterator)
↓
2
next(iterator)
↓
3
Fungsi next() berhubungan dengan special method:
__next__()
Method tersebut menentukan bagaimana iterator memberikan nilai berikutnya.
StopIteration
Iterator harus memiliki cara untuk memberitahu Python bahwa sudah tidak ada nilai yang dapat diberikan.
Python menggunakan exception:
StopIteration
Contohnya:
numbers = [1, 2, 3]
iterator = iter(numbers)
print(next(iterator))
print(next(iterator))
print(next(iterator))
print(next(iterator))
Tiga pemanggilan pertama menghasilkan:
1
2
3
Pemanggilan berikutnya tidak memiliki nilai lagi sehingga menghasilkan:
StopIteration
Secara sederhana:
1 → 2 → 3 → StopIteration
StopIteration merupakan mekanisme standar yang digunakan Python untuk menandai bahwa proses iterasi telah selesai.
Bagaimana for Menangani StopIteration?
Ketika menggunakan for, kita tidak perlu menangani StopIteration secara manual.
Python melakukan mekanisme tersebut secara otomatis.
Secara konseptual, perulangan:
for item in iterable:
print(item)
dapat dipahami seperti:
iterator = iter(iterable)
while True:
try:
item = next(iterator)
print(item)
except StopIteration:
break
Kedua kode tersebut memiliki tujuan yang sama, yaitu mengambil nilai dari iterable satu per satu sampai tidak ada nilai lagi.
Membuat for Loop Sederhana Sendiri
Dengan memahami mekanisme tersebut, kita dapat membuat simulasi sederhana bagaimana for bekerja.
Contohnya:
def special_for_loop(iterable):
iterator = iter(iterable)
while True:
try:
item = next(iterator)
print(item * 2)
except StopIteration:
break
special_for_loop([1, 2, 3])
Output:
2
4
6
Function tersebut melakukan beberapa langkah:
- Mengubah iterable menjadi iterator menggunakan
iter(). - Mengambil nilai menggunakan
next(). - Memproses nilai yang diperoleh.
- Mengulangi proses selama masih terdapat nilai.
- Menangkap
StopIterationketika iterator sudah habis. - Menghentikan perulangan menggunakan
break.
Membuat Iterator dengan Class
Python juga memungkinkan kita membuat object yang memiliki mekanisme iterasi sendiri.
Untuk membuat iterator menggunakan class, kita dapat menggunakan special method:
__iter__()
dan:
__next__()
Contohnya:
class MyGen:
current = 0
def __init__(self, first, last):
self.first = first
self.last = last
def __iter__(self):
return self
def __next__(self):
if MyGen.current < self.last:
num = MyGen.current
MyGen.current += 1
return num
raise StopIteration
Object tersebut dapat digunakan dalam for:
gen = MyGen(0, 100)
for i in gen:
print(i)
Iterator tersebut menghasilkan nilai sampai batas yang ditentukan.
Peran __iter__()
Pada iterator yang dibuat menggunakan class, __iter__() digunakan untuk mengembalikan iterator.
Dalam contoh:
def __iter__(self):
return self
self dikembalikan karena object tersebut bertindak sebagai iterator untuk dirinya sendiri.
Secara sederhana:
Object
↓
__iter__()
↓
Iterator
Peran __next__()
__next__() menentukan bagaimana object menghasilkan nilai berikutnya.
Contohnya:
def __next__(self):
if MyGen.current < self.last:
num = MyGen.current
MyGen.current += 1
return num
raise StopIteration
Selama kondisi masih terpenuhi, method tersebut mengembalikan nilai berikutnya.
Ketika batas telah tercapai:
raise StopIteration
digunakan untuk memberitahu Python bahwa iterasi telah selesai.
Hubungan iter() dengan __iter__()
Fungsi bawaan iter() dan special method __iter__() memiliki hubungan erat.
Ketika kita menulis:
iterator = iter(iterable)
Python menggunakan mekanisme __iter__() dari object tersebut untuk mendapatkan iterator.
Secara konseptual:
iter(object)
↓
object.__iter__()
↓
iterator
Hubungan next() dengan __next__()
Hal yang sama berlaku pada next().
Ketika kita menulis:
next(iterator)
Python menggunakan mekanisme __next__() pada iterator tersebut untuk mendapatkan nilai berikutnya.
Secara konseptual:
next(iterator)
↓
iterator.__next__()
↓
nilai berikutnya
Keseluruhan Mekanisme
Hubungan seluruh konsep dapat digambarkan sebagai berikut:
Iterable
↓
iter()
↓
__iter__()
↓
Iterator
↓
next()
↓
__next__()
↓
Nilai berikutnya
↓
next()
↓
...
↓
Tidak ada nilai lagi
↓
StopIteration
↓
Loop selesai
Inilah mekanisme dasar yang memungkinkan Python melakukan iterasi terhadap berbagai object.
Iterable vs Iterator
Meskipun keduanya berhubungan erat, iterable dan iterator bukan istilah yang sama.
| Konsep | Peran |
|---|---|
| Iterable | Object yang dapat diiterasi |
| Iterator | Object yang menghasilkan nilai satu per satu |
iter() | Mendapatkan iterator dari iterable |
__iter__() | Menyediakan iterator |
next() | Mengambil nilai berikutnya |
__next__() | Menentukan nilai berikutnya |
StopIteration | Menandakan bahwa iterasi telah selesai |
Contoh sederhananya:
List
↓
Iterable
↓
iter(list)
↓
Iterator
↓
next()
↓
Nilai
Hubungan dengan Generator
Konsep ini juga menjelaskan mengapa generator dapat digunakan dalam for.
Generator memiliki mekanisme iterasi sehingga dapat menghasilkan nilai secara bertahap.
Hubungannya:
Iterable
↓
Iterator
↓
Generator
↓
yield
↓
Nilai satu per satu
Dengan memahami mekanisme iterator secara manual, kita dapat melihat bahwa generator sebenarnya menyediakan cara yang lebih praktis untuk menghasilkan nilai secara bertahap tanpa harus selalu membuat class dengan __iter__() dan __next__() sendiri.
Kesimpulan
Perulangan for di Python bekerja menggunakan mekanisme iterable dan iterator.
Secara sederhana, prosesnya adalah:
for
↓
iter()
↓
iterator
↓
next()
↓
nilai
↓
next()
↓
nilai berikutnya
↓
StopIteration
↓
selesai
Konsep penting yang perlu diingat:
- Iterable adalah object yang dapat diiterasi.
- Iterator menghasilkan nilai satu per satu.
iter()digunakan untuk mendapatkan iterator.__iter__()menyediakan iterator.next()mengambil nilai berikutnya.__next__()menentukan mekanisme pengambilan nilai berikutnya.StopIterationmenandakan bahwa iterator sudah selesai.formenangani mekanisme iterasi tersebut secara otomatis.
Memahami mekanisme ini menjadi dasar penting untuk memahami iterator dan generator secara lebih mendalam, sekaligus menjelaskan apa yang sebenarnya terjadi di balik perulangan for Python.