Saat menampilkan daftar peserta, nomor baris tabel, atau peringkat juara, kita butuh dua informasi sekaligus: posisi dan nilainya. Kebiasaan yang dibawa dari bahasa lain adalah range(len(...)) plus pengindeksan manual. Fungsi bawaan enumerate() menyelesaikan kebutuhan yang sama dengan cara yang lebih bersih — dan bekerja pada jauh lebih banyak jenis data.

Pola range(len()) dan Keterbatasannya #

Dua loop berikut menghasilkan output identik — satu memakai pola lama, satu memakai enumerate():

python
buah = ["apel", "jeruk", "mangga"]

# Cara 1: range + indexing
for i in range(len(buah)):
    print(i, buah[i])

print("---")

# Cara 2: enumerate
for i, item in enumerate(buah):
    print(i, item)

Output yang Dihasilkan:

text
0 apel
1 jeruk
2 mangga
---
0 apel
1 jeruk
2 mangga

Bedah cara kerja versi enumerate():

  1. Baris 10 (enumerate(buah)): fungsi menghasilkan aliran pasangan (index, item) — (0, 'apel'), (1, 'jeruk'), (2, 'mangga').
  2. for i, item in ...: setiap tuple pasangan di-unpack langsung ke dua variabel, tanpa pengindeksan buah[i].
  3. Tidak ada len(): enumerate() bekerja di atas protokol iterasi, jadi tidak perlu tahu panjang data di depan.

Keterbatasan pola lama muncul begitu sumbernya bukan sequence. range(len(...)) mensyaratkan objek yang bisa diindeks dengan angka — set, dictionary items, baris file, atau aliran data tidak memenuhi syarat itu:

python
>>> warna = {"merah", "hijau"}
>>> warna[0]
Traceback (most recent call last):
    ...
TypeError: 'set' object is not subscriptable

Set tidak mendukung pengindeksan, sehingga warna[i] langsung gagal. enumerate() tidak peduli — fungsi ini menerima iterable apa pun dan tetap mengeluarkan pasangan posisi-nilai.

Bahkan pada data yang bisa diindeks, pola range(len(...)) tetap membawa risiko tipikal manusia: operator yang salah (i - 1 vs i + 1), penghitung yang lupa disinkronkan setelah data berubah, atau len() yang dipanggil di dalam kondisi loop sehingga membingungkan pembaca. enumerate() memindahkan seluruh urusan posisi ke satu panggilan — kita tinggal memberi nama yang bermakna pada pasangan index, item-nya.

Parameter start #

Nomor posisi tidak selalu dimulai dari nol. Parameter start menggeser angka awal, sangat praktis untuk penomoran yang dibaca manusia:

python
peserta = ["Budi", "Siti", "Agus"]

for peringkat, nama in enumerate(peserta, start=1):
    print(f"peringkat {peringkat}: {nama}")

print("---")

for nomor, nama in enumerate(peserta, start=100):
    print(nomor, nama)

Output yang Dihasilkan:

text
peringkat 1: Budi
peringkat 2: Siti
peringkat 3: Agus
---
100 Budi
101 Siti
102 Agus

Nilai start boleh angka berapa pun, termasuk yang besar. Data aslinya tidak tersentuh — enumerate() hanya memberi nomor pada aliran yang lewat, bukan mengubah sumbernya.

Pola Sehari-hari dengan enumerate #

Kombinasi enumerate() dengan list comprehension dari Chapter List Comprehensions menghasilkan idiom pencarian posisi yang ringkas — semua indeks tempat sebuah nilai muncul:

python
transaksi = ["bola", "raket", "bola", "net", "bola"]

posisi_bola = [i for i, item in enumerate(transaksi) if item == "bola"]
print(posisi_bola)

for i, ch in enumerate("abc"):
    print(i, ch)

Output yang Dihasilkan:

text
[0, 2, 4]
0 a
1 b
2 c

Pada baris 3, method .index() yang hanya menemukan kemunculan pertama tergantikan oleh comprehension yang mengumpulkan semua posisi. Contoh kedua menegaskan bahwa enumerate() juga bekerja pada string — objek iterable apa pun selalu sah.

Pola kedua yang sering muncul adalah membuat tampilan bernomor. Karena enumerate() menghasilkan pasangan siap pakai, ia berkolaborasi langsung dengan f-string di dalam comprehension untuk membangun baris-baris teks rapi:

python
menu = ["nasi goreng", "mie goreng", "sate"]

daftar = [f"{i}. {m}" for i, m in enumerate(menu, start=1)]
for baris in daftar:
    print(baris)

Output yang Dihasilkan:

text
1. nasi goreng
2. mie goreng
3. sate

Satu ekspresi menggabungkan empat hal sekaligus: penomoran dari 1, pengambilan nama menu, format teks, dan pengumpulan hasil ke list daftar — pekerjaan yang dengan pola range(len(...)) membutuhkan append manual di dalam loop terpisah.

Aspekrange(len(buah))enumerate(buah)
Sumber yang didukungsequence berindeks sajasemua iterable
Bentuk yang diterima loopangka, harus indexing sendiripasangan (index, item) siap unpack
Nomor awalselalu 0bisa digeser lewat start
Keterbacaandua lompatan konsepsatu kalimat lugas