Soru geçmişi
enumerate() fonksiyonu, Python'da bir dizinin elemanlarını iterasyon yaparken mevcut indeksin de alınabilmesi için kullanışlı ve idiomatik bir şekilde görünmesi amacıyla ortaya çıkmıştır. Daha önce genellikle ayrı bir sayaç tutmanın önerilmesi, bunun da daha az idiomatik ve okunabilir olması nedeniyle sıkıntı yaratmıştır.
Problem
Döngülerde, yalnızca mevcut değerin değil, bunun yanısıra dizideki indeksinin de bilinmesi sıklıkla gereklidir. İndeksleri ayrı bir değişken (i) kullanarak manuel olarak yönetmek ve range(len(seq)) kullanmak hata yapma riskini artırır (indeks ve değerlerin çelişmesi, kodun tekrar etmesi) ve okunabilirliği azaltır.
Çözüm
enumerate() her adımda mevcut elemanın bir tuple'ını (indeks, değer) döndüren tembel bir iterator sunar. Bu sayede indekslerle şık ve güvenilir bir şekilde çalışabilirsiniz:
colors = ['kırmızı', 'yeşil', 'mavi'] for idx, color in enumerate(colors): print(idx, color)
İterasyon sıfırdan başlar, ancak istenirse farklı bir başlangıç değeri de verilebilir:
for idx, color in enumerate(colors, start=1): print(idx, color)
Ana özellikler:
enumerate() her tür iteratifi destekler ve (indeks, eleman) tuple'ı döner.start parametresi belirtilir.enumerate() ile çalışırken indeksin geri dönüşünü iptal edip yalnızca değerler almak mümkün mü?
Hayır, enumerate() her zaman (indeks, değer) çiftlerini döndürür. Eğer yalnızca değere ihtiyaç varsa, normal bir for döngüsü kullanmalısınız:
for value in my_list: print(value)
enumerate()'yi indexlenebilir olmayan nesnelerle, örneğin jeneratörlerle kullanmak mümkün mü?
Evet, enumerate() her tür iteratif nesneyle çalışır; jeneratörler de bunlar arasında yer alır. İndeksleme değerlerin ortaya çıkış sırasına göre yapılır:
def mygen(): for i in range(3): yield chr(ord('a')+i) for idx, val in enumerate(mygen()): print(idx, val) # 0 a, 1 b, 2 c
Sıfırdan farklı bir başlangıç indeksi otomatik ayarlamak mümkün mü, negatif değerlere ne olur?
Evet, enumerate()'de start argümanı bulunmaktadır. Eğer negatif bir değer verilirse, indeksleme bu değerden başlayacaktır:
for idx, x in enumerate(['a', 'b', 'c'], start=-3): print(idx, x) # -3 a, -2 b, -1 c
range(len(seq)) kullanmak — bu, kodun daha az okunaklı ve idiomatik olmasına sebep olur.Bir takım büyük bir kod tutuyor, sık sık şunları kullanıyor:
for i in range(len(mylist)): process(i, mylist[i])
Avantajlar:
Dezavantajlar:
Refaktörlerden sonra şu şekilde geçiş yapılıyor:
for idx, val in enumerate(mylist): process(idx, val)
Avantajlar:
Dezavantajlar: