Ana içeriğe geç

Python Enumerate Eğitimi

Python enumerate fonksiyonunun ne olduğunu ve günlük veri bilimi görevlerinizde onu nasıl kullanabileceğinizi keşfedin.
· 10 dk. oku

Yapay Zeka ile Keşfedin

Python Enumerate Eğitimi Görseli

Bu eğitimde, Python'da enumerate() fonksiyonunun ne olduğunu, ne zaman kullanıldığını, ne tür nesneler oluşturduğunu, sözdizimini ve nasıl çalıştığını ele alacağız. Ardından, Python'da farklı türde nesnelerin nasıl numaralandırılacağına dair örnekler görecek, enumerate() fonksiyonunun alternatiflerini ve neden aynı görev için daha az uygun olduklarını inceleyeceğiz.

Python'da Enumerate Nedir ve Ne Zaman Kullanılır?

enumerate() fonksiyonu, bir yinelenebilir (öğelerden oluşan bir koleksiyon veya yinelemeyi destekleyen herhangi bir Python nesnesi; örneğin demetler, listeler, kümeler veya dizgeler) alan, perde arkasında öğeleri üzerinde dolaşan ve bir enumerate nesnesi döndüren yerleşik bir Python fonksiyonudur. Başka bir deyişle, bu fonksiyon bir yinelenebilirin her öğesine 1 artan bir sayaç atar ve bu nesne üzerinde döngü kurarken yinelemeleri takip etmemize yardımcı olur. Bir enumerate nesnesi oluşturduktan sonra, bunu bir listeye, demete veya sözlüğe (sırasıyla list(), tuple() veya dict() fonksiyonlarını kullanarak) dönüştürebiliriz ya da doğrudan bu nesne üzerinde döngü kurarak hem öğelere hem de bunların karşılık gelen indekslerine erişebiliriz.

enumerate() fonksiyonunu kullanmak, indeks ve ilgili öğeyi tek seferde döndürdüğü için bellek ve hesaplama verimliliği açısından for döngülerine kıyasla faydalıdır.

Sözdizimi

enumerate() fonksiyonunun sözdizimi oldukça basittir:

enumerate(iterable, start=0)

Burada iterable, numaralandırmak istediğimiz yinelenebilir nesnedir; start ise sayacın başlangıç indeksini tanımlayan isteğe bağlı bir parametredir (varsayılan olarak tipik Python 0 tabanlı indekstir).

enumerate() fonksiyonunu bir yinelenebilir üzerinde uygulamanın başlangıçtaki nesnenin kendisini değiştirmediğine dikkat edin. Bunun yerine, ortaya çıkan enumerate nesnesini daha sonra kullanabilmek istiyorsak bir değişkene atamalıyız.

Şimdi bu fonksiyonun farklı türde Python yinelenebilirleri üzerinde nasıl çalıştığını görelim.

Listeyi Numaralandırma

Önce enumerate() fonksiyonunu bir Python listesi üzerinde uygulayalım:

drinks = ['tea', 'coffee', 'cappuccino', 'lemonade']
enumerated_drinks = enumerate(drinks)
print(type(enumerated_drinks))
print(enumerated_drinks)

 Çıktı:

<class 'enumerate'>
<enumerate object at 0x000002DC3A1145C0>

Ortaya çıkan nesnenin türü enumerate'tür ve yazdırmayı denediğimizde, nesne türünü ve bilgisayar belleğinde nerede depolandığını tekrar doğrulamış olduk. Bu nesnenin ilk öğesine, bir Python listesi veya demetinde yaptığımız gibi erişmeyi deneyelim:

print(enumerated_drinks[0])

 Çıktı:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_5948/1233607596.py in <module>
----> 1 print(enumerated_drinks[0])

TypeError: 'enumerate' object is not subscriptable

Bir enumerate nesnesinin bileşenlerine bu şekilde erişilemeyeceğini belirten bir hata aldık. Bunun yerine, bu amaçla, onu bir listeye, demete veya sözlüğe dönüştürmemiz ya da enumerate nesnesi üzerinde doğrudan döngü kurmamız gerekir. enumerate nesnemizi bir listeye dönüştürelim:

list_enumerated_drinks = list(enumerated_drinks)
print(list_enumerated_drinks)

 Çıktı:

[(0, 'tea'), (1, 'coffee'), (2, 'cappuccino'), (3, 'lemonade')]

Artık ortaya çıkan listenin iç yapısını net bir şekilde görüyoruz: her öğe, ilk elemanı özgün listedeki ilgili öğenin indeksi, ikinci elemanı ise öğenin kendisi olan 2 elemanlı bir demeti temsil eder. Bu listenin öğelerine erişmek için yaygın dizinleme yaklaşımını kullanabiliriz:

print(list_enumerated_drinks[0])
print(list_enumerated_drinks[0][1])

 Çıktı:

(0, 'tea')
tea

Şimdi de, özgün listeden oluşturulan bir enumerate nesnesini bir demete dönüştürmeyi deneyelim. Ayrıca bu kez start isteğe bağlı parametresini 1 olarak ayarlayacağız:

tuple_enumerated_drinks = tuple(enumerate(drinks, start=1))
print(tuple_enumerated_drinks)

 Çıktı:

((1, 'tea'), (2, 'coffee'), (3, 'cappuccino'), (4, 'lemonade'))

Yukarıdaki demetin iç yapısı, daha önce oluşturulan listeninkiyle aynıdır. Ancak bu kez sayacı değiştirerek Python'un 0 tabanlı indekslemesi yerine daha "insani" bir sayım yaptık.

Burada bahsetmeye değer ilginç bir enumerate yöntemi var: next() yöntemi. enumerated_drinks nesnesini yeniden oluşturalım ve bu yöntemi uygulamada görelim:

enumerated_drinks = enumerate(drinks)
print(next(enumerated_drinks))
print(next(enumerated_drinks))
print(next(enumerated_drinks))
print(next(enumerated_drinks))
print(next(enumerated_drinks))

 Çıktı:

(0, 'tea')
(1, 'coffee')
(2, 'cappuccino')
(3, 'lemonade')

---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_5948/330134057.py in <module>
      4 print(next(enumerated_drinks))
      5 print(next(enumerated_drinks))
----> 6 print(next(enumerated_drinks))

StopIteration: 

Gördüğümüz gibi, bu yöntemi bir enumerate nesnesi üzerinde her çağırdığımızda, ondan bir sonraki öğeyi döndürür (ve her öğenin ilgili sayaç-öğe çiftini içeren 2 elemanlı bir demet olduğunu yine doğrulayabiliriz). Tüm öğeler bittiğinde enumerate nesnesi tükenir ve next() yöntemini çağırma girişimi StopIteration hatası fırlatır. Nitekim, şimdi bu enumerate nesnesini bir listeye dönüştürmeyi denersek boş olduğunu göreceğiz

print(list(enumerated_drinks))

 Çıktı:

[]

Bu, next() yönteminin enumerate nesnesine her uygulanışında nesneden bir öğe alındığı, dolayısıyla her seferinde biraz daha küçüldüğü ve tamamen tükenene kadar devam ettiği anlamına gelir. Enumerate nesnelerinin bu özelliğini, bunlar üzerinde for döngülerinin uygulanmasını tartışırken de göreceğiz.

Python listeleri ve diğer temel Python kavramları hakkında daha fazla bilgi edinmek isterseniz DataCamp'in Introduction to Python kursunu alabilirsiniz.

Bir Demeti Numaralandırma

enumerate() fonksiyonunun bir demet üzerinde uygulanması, bir liste üzerindekiyle aynıdır:

drinks = ('tea', 'coffee', 'cappuccino', 'lemonade')
enumerated_drinks = enumerate(drinks)
print(enumerated_drinks)

 Çıktı:

<enumerate object at 0x000002DC3A098D40>

Yine, öğelerine yaygın Python dizinlemesiyle erişilemeyen bir enumerate nesnesi elde ettik. Bu nesneyi bu kez bir sözlüğe dönüştürelim:

dict_enumerated_drinks = dict(enumerated_drinks)
print(dict_enumerated_drinks)

 Çıktı:

{0: 'tea', 1: 'coffee', 2: 'cappuccino', 3: 'lemonade'}

Ortaya çıkan sözlüğün her anahtar:değer çifti, ilgili sayaç-öğe çiftini temsil eder. Sözlüğün değerlerine yaygın Pythonic bir şekilde erişebiliriz:

print(dict_enumerated_drinks[0])
print(dict_enumerated_drinks[3])

 Çıktı:

tea
lemonade

Python sözlükleri ve pandas hakkında daha derine inmek isterseniz Intermediate Python kursuna göz atın. 

Bir Dizgeyi Numaralandırma

Python dizgeleri karakter dizileri olduğundan ve dolayısıyla yinelenebilir nesneler olduğundan, bir dizge için de bir enumerate nesnesi oluşturabiliriz:

enumerated_hello_world = enumerate('Hello, World!', start=10)
print(enumerated_hello_world)

 Çıktı:

<enumerate object at 0x000002DC3A145C40>

Daha önce yaptığımız gibi, bu nesneyi bir listeye dönüştürelim:

list_enumerated_hello_world = list(enumerated_hello_world)
print(list_enumerated_hello_world)

 Çıktı:

[(10, 'H'), (11, 'e'), (12, 'l'), (13, 'l'), (14, 'o'), (15, ','), (16, ' '), (17, 'W'), (18, 'o'), (19, 'r'), (20, 'l'), (21, 'd'), (22, '!')]

Daha önce tanıdık olan 2 elemanlı demetleri görüyoruz; ilk eleman dizgedeki ilgili karakterin sayacıdır (bu durumda 10'dan başlayarak) ve ikinci eleman ise karakterin kendisidir. Boşluk ve noktalama işaretleri de sayılır.

enumerated_hello_world nesnesini bu kez start=10 olmadan yeniden oluşturalım ve üzerinde next yöntemini uygulayalım:

enumerated_hello_world = enumerate('Hello, World!')
print(next(enumerated_hello_world))
print(next(enumerated_hello_world))
print(next(enumerated_hello_world))
print(next(enumerated_hello_world))
print(next(enumerated_hello_world))
print(next(enumerated_hello_world))
​
# Creating a list from the remaining enumerate object
print(list(enumerated_hello_world))

 Çıktı:

(0, 'H')
(1, 'e')
(2, 'l')
(3, 'l')
(4, 'o')
(5, ',')
[(6, ' '), (7, 'W'), (8, 'o'), (9, 'r'), (10, 'l'), (11, 'd'), (12, '!')]

Yukarıdaki kod parçasının son satırında, next() yöntemini kullanmayı bırakıp enumerated_hello_world nesnesini bir listeye dönüştürdük. Ortaya çıkan liste, next() yönteminin birden çok kez uygulanmasından sonra başlangıçtaki enumerate nesnesinde kalan karakterleri içerir.

For Döngüsüyle Numaralandırma

Son olarak, enumerate() fonksiyonunun bir for döngüsüyle birlikte nasıl çalıştığını görelim:

for item in enumerate(['tea', 'coffee', 'cappuccino', 'lemonade']):
  print(item)

 Çıktı:

(0, 'tea')
(1, 'coffee')
(2, 'cappuccino')
(3, 'lemonade')

Her yinelemede, tıpkı next() yöntemini kullandığımızda olduğu gibi ilgili sayaç-öğe demeti döndürülür. Yukarıdaki koddan açıkça görünmese de enumerate nesnesi her yinelemede öğelerini (yani 2 elemanlı demetleri) teker teker kaybeder. Bunu göstermek için yukarıdaki kodu farklı bir biçimde yeniden yazalım ve tüm yinelemeler tamamlandıktan sonra ortaya çıkan listenin uzunluğunu kontrol edelim:

drinks = ['tea', 'coffee', 'cappuccino', 'lemonade']
enumerated_drinks = enumerate(drinks)
​
for item in enumerated_drinks:
  print(item)
 
print(list(enumerated_drinks))

 Çıktı: 

(0, 'tea')
(1, 'coffee')
(2, 'cappuccino')
(3, 'lemonade')
[]

next() yönteminin uygulanmasında olduğu gibi, bir enumerate nesnesi üzerinde yineleme yapmak onu kademeli olarak tüketir.

Ancak, önceki kod parçasına geri dönelim. Her 2 elemanlı demetten her bir öğeye ayrı ayrı nasıl erişebiliriz? Bu amaçla bir yineleme değişkeni daha ekleyip demetleri açacağız:

for count, drink in enumerate(['tea', 'coffee', 'cappuccino', 'lemonade']):
  print(count, drink)

 Çıktı:

0 tea
1 coffee
2 cappuccino
3 lemonade

Yukarıda, her demet için iki değişken döndürdük: biri öğenin sayacı, diğeri öğenin kendisi için.

Aynı işlemi enumerate() fonksiyonunu kullanmadan da uygulayabileceğimizi unutmayın. Örneğin, döngünün dışında bir sayaç değişkeni tanımlayabilir ve döngünün her yinelemesinde bunu 1 artırabiliriz:

count = 0
for drink in ['tea', 'coffee', 'cappuccino', 'lemonade']:
  print(count, drink)
  count += 1

 Çıktı:

0 tea
1 coffee
2 cappuccino
3 lemonade

Alternatif olarak, önceden tanımlanmış bir liste (veya demet, dizge vb.) üzerinde range() ve len() fonksiyonlarının bir kombinasyonunu kullanabiliriz:

drinks = ['tea', 'coffee', 'cappuccino', 'lemonade']
for count in range(len(drinks)):
  print(count, drinks[count])

 Çıktı:

0 tea
1 coffee
2 cappuccino
3 lemonade

Dahası, enumerate() fonksiyonunun her iki alternatifinde de sayacı sıfırdan başlamayacak şekilde ayarlayabiliriz:

count = 1
for drink in ['tea', 'coffee', 'cappuccino', 'lemonade']:
  print(count, drink)
  count += 1
​
print('\n')
 
drinks = ['tea', 'coffee', 'cappuccino', 'lemonade']
for count in range(len(drinks)):
  print(count + 1, drinks[count])

 Çıktı:

1 tea
2 coffee
3 cappuccino
4 lemonade


1 tea
2 coffee
3 cappuccino
4 lemonade

Ancak, enumerate() fonksiyonunun uygulanmasıyla karşılaştırıldığında, yukarıdaki iki yaklaşım daha hantal, hataya açık (örneğin, her yinelemede sayacı manuel olarak güncellemeyi unutabiliriz) ve daha fazla kod gerektirir. Bu nedenle, her yinelemede bir yinelenebilirin hem sayacına hem de öğesine erişmemiz gerektiğinde enumerate() fonksiyonunu kullanmak en Pythonic yaklaşımdır.

Sonuç

Bu eğitimde, Python'daki enumerate() fonksiyonu hakkında; kullanım alanları, olası alternatifleri ve nihayetinde neden alternatiflerinden daha etkili olduğuna kadar pek çok şeyi öğrendik.  enumerate() fonksiyonu çoğu başlangıç seviyesindeki Python kullanıcısına tanıdık gelmeyebilir ve hatta ileri düzey programcılar bile bu son derece kullanışlı fonksiyonun farkında olmayabilir. 

enumerate() hakkında daha fazla bilgi edinmek isterseniz, yineleyicileri ve yinelenebilirleri ayrıntılı olarak inceleyen ve yeni becerileri pratik etmek için interaktif alıştırmalar sunan Python Data Science Toolbox (Part 2) kursunu değerlendirebilirsiniz. Ayrıca, diğer Python kavramlarında ustalaşmak istiyorsanız, çeşitli beceri ve kariyer programları, yardımcı kılavuzlar, eğitimler, Python sertifikaları ve değerlendirme testleri sunan Learn Python with DataCamp ilginizi çekebilir. 

Konular

İlgili