Sorunun Tarihi:
enumerate() fonksiyonu Python 2.3'te ortaya çıktı ve artık koleksiyonları dönerken elemanın ve elemanın dizini ile eşzamanlı olarak erişmenin standart yoludur. enumerate() öncesinde programcılar sıklıkla kendi sayaçlarını oluşturuyor veya range(len(sequence)) fonksiyonunu kullanıyorlardı; bu da kullanışsız ve okunaksızdı.
Sorun:
Standart for döngüsü yalnızca değerleri döner. Dizin erişimi için sıklıkla range(len(...)) kullanılır, bu da tüm yinelemeli nesneler için işe yaramaz (örneğin, jeneratörler, dizeler ve değişken uzunluktaki demetler gibi). Bu hatalara yol açar ve kodu karmaşıklaştırır.
Çözüm:
enumerate() çiftlerini (indeks, eleman) döndürür, bu da standart olmayan koleksiyonlar veya filtrelenmiş jeneratörler için geçerli olan mevcut elemanın indeksini almayı sağlar. Fonksiyonun ikinci isteğe bağlı bir argümanı vardır - sayaç için başlangıç değeri.
Kod Örneği:
kelimeler = ['elma', 'muz', 'kiraz'] for idx, kelime in enumerate(kelimeler, 1): print(f"{idx}: {kelime}") # Çıktı: # 1: elma # 2: muz # 3: kiraz
Ana Özellikler:
Neden fonksiyonlarda genellikle range(len(seq)) yerine enumerate kullanırız?
Cevap: range(len(seq)) yalnızca indeks erişimi olan sıralama için işe yarar ve yineleme sırasında uzunluk değişikliklerini dikkate almaz. Ayrıca, daha az okunabilir ve jeneratörler için daha yavaş veya hiçbir şekilde çalışmaz. enumerate() herhangi bir yinelemeli koleksiyon için güvenli bir indeks-değer çiftine erişim sağlar.
Kod Örneği:
# Jeneratör ile çalışmaz: gen = (x for x in range(5)) for i in range(len(gen)): print(i) # Hata: jeneratörün boyutu yok
Liste elemanlarını dolaşırken değişiklik yapmak için enumerate kullanabilir miyiz?
Cevap: Evet, ancak değerleri kaydetmek için indeksler üzerinde döngü yapmalısınız. Aksi takdirde, yalnızca değerlere göre iterasyon yaparsanız, nesnenin bir kopyasını değiştirirsiniz, orijinalini değil.
Kod Örneği:
sayilar = [1, 2, 3] for idx, val in enumerate(sayilar): sayilar[idx] = val * 2 # sayilar = [2, 4, 6]
Eğer enumerate'a iterasyon sırasında değişen bir nesne verirseniz, ne döner?
Cevap: Koleksiyon, iterasyon sırasında değişirse (örneğin, elemanlar silinirse), davranış beklenmedik olabilir çünkü enumerate dahili iteratör üzerinden gider; bu da kayabilir. Bu nedenle, yineleme sırasında koleksiyonu değiştirmek önerilmez.
range(len(...)) kullanım.Olumsuz Durum
Programcı bir liste üzerinde range(len(list)) kullanarak döngü yapar ve o sırada elemanları siler. Sonuç — indeksler kayar, bazı elemanlar atlanır.
Artılar:
Eksiler:
Olumlu Durum
enumerate() kullanılır, bu arada gerekli elemanların yeni bir listesini oluşturur veya indeks üzerinden değeri değiştirir, ancak liste döngüde değişmez.
Artılar:
Eksiler: