enumerate ve zip: Python Döngülerinde Sayaç ve Eşleştirme
Beceri rehberi

enumerate ve zip: Python Döngülerinde Sayaç ve Eşleştirme

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 5 dk okuma

enumerate döngüde sıra numarasını, zip ise birden fazla listeyi aynı anda dolaşmayı sağlar. Rehber ikisinin kalıplarını, farklı uzunluktaki listelerdeki sessiz kayıp riskini ve doğru çözümü gösterir.

Bir bakışta

  1. Elle sayaç yerine enumerate kullanılır. Sıra numarası döngü başlığında gelir; artırmayı Python yapar.
  2. enumerate varsayılan olarak sıfırdan sayar. start parametresi sayacı istediğiniz değerden başlatır; numaralı listeler için kullanışlıdır.
  3. zip listeleri aynı pozisyondan eşleştirir. Her adımda her listeden bir öğe alıp demet kurar; sözlük üretmek için de kullanılır.
  4. Farklı uzunlukta listelerde zip varsayılan olarak durur. Kısa liste bitince fazla öğeler sessizce atlanır; strict=True bunu hataya çevirir.
  5. Her ikisi de tembel nesne üretir. Bir kez dolaşılınca biter; tekrar kullanılacaksa listeye çevrilir.

Döngüde sayaç tutmanın alışılmış yolu ve sorunu

Bir listeyi dolaşırken hem sıra numarasına hem de değere ihtiyaç duyduğunuz çok olur: raporda satır numarası yazmak, hatalı kaydın kaçıncı satırda olduğunu bulmak, her öğeyi bir sıra etiketiyle yazdırmak gibi. İlk akla gelen çözüm elle sayaç tutmak ya da range ile uzunluk üzerinden indeks üretmektir.

siparisler = ['kargo', 'iade', 'degisim']

sayac = baslangic for siparis in siparisler: print(sayac, siparis) sayac += artis

Bu kod çalışır ama sayacın başlatılması, artırılması ve unutulması gibi küçük hata kaynakları taşır. range(len(siparisler)) ile indeks üretip siparisler[i] ile değere ulaşmak da okunmasını zorlaştırır ve yalnızca indekslenebilir türlerde işe yarar.

Python bu iki ihtiyacı yerleşik iki yardımcıyla karşılar. enumerate sıra numarasını, zip ise birden fazla diziyi aynı anda dolaşmayı üstlenir. İkisi de bir iterable alır ve bir demet akışı üretir; döngü başlığında demet doğrudan açılır.

Şekil 1

Elle sayaç tutmak yerine enumerate kullanılır

Aynı iş, daha az hata kaynağı

Elle sayaç
enumerate
Sayaç döngüden önce başlatılır
Sayaç döngü başlığında gelir
Her turda elle artırılır
Python artırmayı kendisi yapar
Artırmayı unutmak sessiz hata üretir
Değer ve sıra aynı satırda açılır
Kaynak: Python belgeleri: yerleşik işlevler (enumerate)Mindset Institute

enumerate ile sıra numarası ve değer

Python belgelerine göre enumerate, bir iterable alır ve her adımda bir sayaç ile iterable'dan gelen değeri içeren demet döndüren bir nesne üretir. Sayaç varsayılan olarak sıfırdan başlar; start parametresiyle başka bir değerden başlatılabilir.

gorevler = ['rapor hazırla', 'mail yanıtla', 'toplantı notu yaz']

for sira, gorev in enumerate(gorevler): print(sira, gorev)

for sira, gorev in enumerate(gorevler, start=baslangic): print(f'{sira}. {gorev}')

İlk döngü bilgisayar mantığıyla sıfırdan sayar. İkincisi insanlara gösterilecek numaralı liste için daha uygundur; start ile numaralandırma bir kez, döngü başlığında belirlenir.

Pratikte en sık kullanım, veri satırlarını denetlerken hatalı satırın yerini söylemektir: for satir_no, kayit in enumerate(kayitlar, start=baslangic) yazıp bozuk kaydı satir_no ile raporlarsınız. Bir dosyayı satır satır okurken de aynı kalıp işe yarar, çünkü dosya nesnesi de bir iterable'dır.

Bir ayrıntı: enumerate bir liste değil, tembel bir nesnedir. Tüm demetleri hemen üretmez, döngü ilerledikçe verir. Sonuçları liste olarak görmek isterseniz list(enumerate(gorevler)) yazarsınız. Sözlük kurmak için de dict(enumerate(gorevler)) kullanılabilir; sıra numaraları anahtar olur.

zip ile birden fazla listeyi birlikte dolaşmak

Ürün adları bir listede, fiyat bilgileri başka bir listede, stok durumu üçüncüsünde tutuluyorsa ve her listenin aynı sırası aynı kaydı anlatıyorsa, zip bu listeleri sırayla eşleştirir. Her adımda her iterable'dan bir öğe alır ve bunları bir demette birleştirir.

adlar = ['Ayşe', 'Mehmet', 'Elif'] roller = ['analist', 'yönetici', 'tasarımcı']

for ad, rol in zip(adlar, roller): print(ad, rol)

eslesme = dict(zip(adlar, roller))

İlk kullanım iki listeyi tek döngüde dolaşır. İkincisi, biri anahtar biri değer olan iki listeden hızlıca sözlük kurar. Veri temizlemede başlık listesi ile değer listesini birleştirip kayıt sözlüğü üretmek tipik bir kullanımdır.

zip aynı şekilde ikiden fazla iterable ile de çalışır. Ayrıca yıldız operatörüyle tersine de kullanılır: Python belgelerinin gösterdiği gibi zip(*eslesmis_ciftler), eşleşmiş çiftlerden iki ayrı dizi çıkarır. Çiftler listesini sütunlara ayırmanın en kısa yolu budur.

enumerate ve zip birlikte kullanılabilir. Sıra numarasıyla birlikte iki listeyi dolaşmak için döngü başlığına parantez açarak yazarsınız: for sira, (ad, rol) in enumerate(zip(adlar, roller)). Burada enumerate dıştaki, zip içteki demeti üretir; iç demetin parantezle açılması şarttır.

Uzunlukları farklı listelerde zip'in davranışı

zip'in en çok yanlış anlaşılan yönü, listeler farklı uzunlukta olduğunda ne yaptığıdır. Python belgelerine göre varsayılan davranış, en kısa iterable bitince durmaktır; daha uzun olanların kalan öğeleri sessizce atlanır. Hata verilmez, uyarı çıkmaz.

Bu, veride sessiz kayıp demektir. Müşteri adları listesinde üç, telefon listesinde iki kayıt varsa üçüncü müşteri çıktıdan hiçbir uyarı olmadan düşer. Eşleşmesi zorunlu verilerde bu davranış istenmez.

İki çözüm vardır. Birincisi, strict=True parametresidir: belgelere göre bir iterable diğerlerinden önce biterse ValueError oluşur. Böylece uzunluk uyuşmazlığı fark edilir ve veri kaynağındaki sorun düzeltilebilir. İkincisi, itertools modülündeki zip_longest işlevidir; kısa kalanları fillvalue ile doldurur, doldurma değeri belirtilmezse None kullanılır.

for ad, telefon in zip(adlar, telefonlar, strict=True): kaydet(ad, telefon)

Karar basit: eşleşme zorunluysa strict=True, eksik değerlerin boş bırakılıp yine de işlenmesi isteniyorsa zip_longest, kısa olan kadarıyla yetinmek bilinçli bir tercihse varsayılan zip kullanılır.

Şekil 2

Uzunluklar farklıysa zip'in üç yolu vardır

Listeler farklı uzunluktaysa ne yapılmalı?
  1. Her kayıt eşleşmek zorundazip(..., strict=True)Uyuşmazlık ValueError ile görünür olur.
  2. Eksikler boş değerle doldurulacakitertools.zip_longestfillvalue verilmezse None kullanılır.
  3. Kısa olan kadarı yeterlizipFazla öğeler sessizce atlanır; bilinçli tercih olmalı.
Kaynak: Python belgeleri: zip ve itertools.zip_longestMindset Institute

Yaygın hatalar ve doğru kullanım

enumerate ve zip tembel nesnelerdir, bu yüzden bir kez tüketilince biter. zip nesnesini bir değişkende saklayıp iki kez dolaşmak istediğinizde ikinci döngünün boş çalıştığını görürsünüz. Birden fazla kez kullanılacaksa list(zip(...)) ile listeye çevirin.

Sık yapılan diğer hatalar:

  • Demeti açarken değişken sayısını yanlış vermek: üç iterable'ı zip'leyip döngüde iki değişken yazmak ValueError üretir.
  • enumerate'in döndürdüğü demetin sırasını karıştırmak: önce sayaç, sonra değer gelir; for gorev, sira yazarsanız adlar yer değiştirir.
  • zip ile dolaşırken listeleri aynı anda değiştirmek: dolaşılan listeye öğe ekleyip silmek beklenmeyen sonuç verir, yeni bir liste üretmek daha güvenlidir.
  • Sözlük üretirken anahtar listesinde tekrar bırakmak: dict(zip(...)) aynı anahtarın son değerini tutar, önceki kayıt kaybolur.
  • Sırası anlamlı olmayan verilerde zip kullanmak: kümeler ve eski sözlük varsayımları sıra garantisi vermez, eşleşme beklediğiniz gibi çıkmayabilir.

Okunurluk için de bir kural koymak iyidir: sayaç gerçekten gerekmiyorsa enumerate kullanmayın, doğrudan değeri dolaşın. range(len(x)) yazdığınız her yer, enumerate ya da zip ile daha okunur hale getirilebilir mi diye kontrol edilmeye değer.

Bu beceriyi Mindset programlarında nerede çalışırsınız

Python ile Programlama Eğitimi, Döngüler ve Veri Yapıları başlıklı modülleri içerir; enumerate ve zip bu iki konunun kesiştiği yerdedir. Data Science Bootcamp ise Python'a Giriş, Veri Yapıları ve Fonksiyonlar modülleriyle aynı temeli veri çalışmasına bağlar. Satır numaralı kayıt denetimi ve paralel listeleri eşleştirme, veri temizleyen analistin her gün yazdığı küçük kalıplardır.

İlgili Mindset programı

Python ile Programlama Eğitimi

Sık sorulanlar

Sık sorulan sorular

enumerate sıfırdan değil birden nasıl başlatılır?

start parametresiyle: enumerate(liste, start=baslangic) yazarsınız ve sayaç verdiğiniz değerden başlar. Numaralı listeler ve kullanıcıya gösterilen satır numaraları için idealdir. Bu parametre yalnızca sayacı etkiler, dolaşılan öğelerin sırası ve içeriği değişmez; listenin ilk öğesi yine ilk gelir.

zip kaç liste ile kullanılabilir?

İstediğiniz kadar iterable verebilirsiniz; her adımda her birinden bir öğe alınır ve hepsi bir demette birleşir. Demeti döngü başlığında açarken değişken sayısının iterable sayısıyla aynı olması gerekir. Çok sayıda liste gerekiyorsa genellikle veriyi sözlük ya da tablo yapısında tutmak daha okunur bir tasarımdır.

zip ile oluşturulan nesne neden ikinci kez dolaşılınca boş çıkıyor?

zip tembel bir iteratördür; öğeleri döngü ilerledikçe üretir ve tükendiğinde biter. Aynı nesneyi yeniden dolaştığınızda üretecek öğe kalmamıştır. Birden fazla kez kullanmanız gerekiyorsa sonucu list(zip(...)) ile listeye çevirin ya da her döngü için zip'i yeniden çağırın.

enumerate yalnızca listelerde mi çalışır?

Hayır, her iterable ile çalışır: liste, demet, metin, sözlük, dosya nesnesi ya da bir üreteç olabilir. Metinde karakterleri, dosyada satırları, sözlükte anahtarları sıra numarasıyla birlikte verir. Yalnızca indeksle erişime dayanan range(len()) yaklaşımından en önemli farkı budur.

Ne zaman enumerate, ne zaman zip kullanmalıyım?

Tek bir diziyi dolaşırken sıra numarası da lazımsa enumerate, birden fazla diziyi aynı pozisyondan eşleştirerek dolaşmak istiyorsanız zip kullanılır. İkisi aynı döngüde birleşebilir. Hiçbir sıra bilgisine ya da eşleştirmeye ihtiyaç yoksa düz for döngüsü en sade seçenektir.

Python enumerate ve zip Kullanımı: Örneklerle