Loop for mengiterasi koleksi yang sudah ada, tetapi sering kita butuh deret angka: hitung 1 sampai 10, lintasi indeks tabel, atau buat deret genap. Fungsi built-in range() menghasilkan deret angka sesuai permintaan tanpa kita menulis list angka secara manual. Pada Chapter ini kita bedah tiga bentuk range(), sifat lazy evaluation yang membuat range() hemat memori, dan jebakan off-by-one yang paling sering menjebak pemula.
Bentuk Dasar range(stop) #
Dengan satu argument, range(stop) menghasilkan angka mulai dari 0 sampai sebelum stop. Nilai stop sendiri tidak pernah ikut — inilah konvensi eksklusif ujung yang dipakai konsisten di seluruh Python.
for angka in range(5):
print(f"Angka ke-{angka}")Output yang Dihasilkan:
Angka ke-0
Angka ke-1
Angka ke-2
Angka ke-3
Angka ke-4range(5) memberi lima angka: 0, 1, 2, 3, 4. Hasil evaluasi range() bukan list, melainkan object range yang siap diiterasi — kita bisa mengintip isinya lewat list():
>>> range(3)
range(0, 3)
>>> list(range(3))
[0, 1, 2]range(start, stop, step) #
Bentuk lengkapnya menerima tiga argument: nilai awal, batas akhir (eksklusif), dan jarak antar angka.
| Bentuk | Artinya | Contoh hasil |
|---|---|---|
range(stop) | mulai 0, jarak 1 | range(5) → 0, 1, 2, 3, 4 |
range(start, stop) | mulai start, jarak 1 | range(2, 6) → 2, 3, 4, 5 |
range(start, stop, step) | mulai start, jarak step | range(2, 9, 3) → 2, 5, 8 |
Mari kita lihat ketiganya sekaligus, termasuk step negatif untuk berhitung mundur:
print(list(range(5)))
print(list(range(2, 11, 2)))
print(list(range(10, 0, -2)))Output yang Dihasilkan:
[0, 1, 2, 3, 4]
[2, 4, 6, 8, 10]
[10, 8, 6, 4, 2]Baris kedua menghasilkan bilangan genap dari 2 hingga 10 karena step=2 melompati satu angka setiap kali. Baris ketiga memakai step negatif: deret berjalan mundur dari 10 dan berhenti sebelum menyentuh 0, sehingga hasilnya 10, 8, 6, 4, 2.
Lazy: Deret yang Tidak Dibuat di Memori #
range() tidak menyimpan seluruh angka di memori. Object range hanya mencatat nilai start, stop, dan step, lalu menghitung tiap angka hanya saat dibutuhkan — inilah yang disebut lazy evaluation.
deret = range(1_000_000)
print(deret)
print(deret[0], deret[999_999])
print(len(deret))Output yang Dihasilkan:
range(0, 1000000)
0 999999
1000000Mari kita telaah apa yang terjadi pada baris-baris kode di atas:
- Baris 3 (
print(deret)): representasi object hanya menampilkan parameternya — satu juta angka tidak pernah dibuat sekaligus. - Baris 4 (
deret[0], deret[999_999]):rangemendukung indexing, dan tiap angka dihitung pada saat diakses. - Baris 5 (
len(deret)): jumlah angka dihitung dengan rumus, bukan dengan menghitung satu per satu.
Berkat sifat lazy, range(1_000_000) memakai memori yang sama kecilnya dengan range(5). Fungsi list(range(...)) memang bisa dipakai untuk melihat isi, tetapi pola tersebut memaksa seluruh angka dibuat sekaligus di memori — gunakan hanya untuk deret kecil saat inspeksi.
Jebakan Off-by-One #
Karena stop selalu dikecualikan, target “angka 1 sampai 5” tidak tercapai dengan range(1, 5). Perhatikan perbandingan berikut:
# Tujuan: mencetak angka 1 sampai 5
print("range(1, 5):", list(range(1, 5)))
print("range(1, 6):", list(range(1, 6)))Output yang Dihasilkan:
range(1, 5): [1, 2, 3, 4]
range(1, 6): [1, 2, 3, 4, 5]range(1, 5) hanya menghasilkan empat angka — angka 5 terpotong. Untuk menyertakan angka 1 sampai 5, nilai stop harus satu di atas batas atas yang diinginkan: range(1, 6).
Dengan range(), loop for dapat menyusuri deret angka berapa pun arahnya. Selanjutnya kita pelajari cara menghentikan loop lebih awal dan melewati iterasi tertentu pada Chapter break dan continue.