/webodası
Python Dersleri

Python Dersleri #23: Demet Metotları ve Paket Açma

Uzmoon · · 7 dk

Bu derste Python demetlerinin yerleşik count ve index metotlarını inceliyor, demet elemanlarını değişkenlere tek hamlede atayan paket açma (unpacking) tekniğini ve genişletilmiş yıldız (*) işlecini öğreniyoruz.

Bu Dersin Amacı

Bu dersin amacı, Python demetlerinde bulunan yerleşik count() ve index() metotlarını doğru şekilde kullanmayı ve demet içerisindeki verileri değişkenlere tek hamlede aktaran paket açma (unpacking) tekniklerini kavramaktır.

Demetlerin Yerleşik Metotları

Önceki dersimizde demetlerin (tuple) değiştirilemez (immutable) veri tipleri olduğunu öğrenmiştik. Bir demet oluşturulduktan sonra bellekteki yapısı korunur; demete yeni bir eleman eklenemez, mevcut bir eleman silinemez veya sırası değiştirilemez. Bu temel yapısal kural nedeniyle demetler, listelere kıyasla son derece sade bir metot kümesine sahiptir.

Listelerde sıkça başvurduğumuz append(), insert(), remove() veya sort() gibi koleksiyonu yerinde değiştiren metotlar demetlerde yer almaz. Python'da demet nesnelerinin doğrudan çağırabildiği yalnızca iki adet yerleşik metot bulunmaktadır: count() ve index().

count() Metodu ile Eleman Sayma

count() metodu, argüman olarak iletilen bir değerin demet içerisinde kaç defa tekrarlandığını hesaplar ve sonucu tam sayı (integer) olarak döndürür. Aranan değer demet içerisinde hiç yer almıyorsa metot herhangi bir hata fırlatmaz, güvenli bir şekilde 0 değerini üretir.

adet = demet.count(aranan_deger)

index() Metodu ile Eleman Sırasını Bulma

index() metodu, parametre olarak verilen bir değerin demet içinde ilk görüldüğü indeks numarasını döndürür. Python'da indekslemenin sıfırdan (0) başladığı kuralı demetler için de geçerlidir. Eğer aradığınız eleman demet içerisinde birden fazla kez geçiyorsa, metot yalnızca ilk eşleşmenin indeksini verir.

index() metodunun kritik bir çalışma kuralı vardır: Aranan değer demette mevcut değilse Python çalışma zamanında bir ValueError hatası üretir. Programınızın beklenmedik şekilde kesintiye uğramasını önlemek adına arama yapmadan önce in işleci ile kontrol gerçekleştirmek veya arama işlemini hata yakalama bloklarıyla güvenceye almak doğru bir yaklaşımdır.

Ayrıca index() metoduna aramanın hangi indeks aralığında yapılacağını belirten başlangıç ve bitiş sınırları da isteğe bağlı olarak verilebilir: demet.index(deger, baslangic, bitis).

Aşağıdaki kod örneğinde count() ve index() metotlarının günlük senaryolarda nasıl çalıştığını ve güvenli arama yöntemini inceleyelim:

sayilar = (10, 25, 30, 25, 40, 25, 50)

# count() ile eleman sayma
yirmibes_sayisi = sayilar.count(25)
yuz_sayisi = sayilar.count(100)

print("25 sayisi demette", yirmibes_sayisi, "kez geciyor.")
print("100 sayisi demette", yuz_sayisi, "kez geciyor.")

# index() ile ilk gorulen konumu bulma
ilk_konum = sayilar.index(25)
print("25 sayisinin ilk goruldugu indeks:", ilk_konum)

# Guvenli indeks arama
aranan = 70
if aranan in sayilar:
    konum = sayilar.index(aranan)
    print(aranan, "sayisinin indeksi:", konum)
else:
    print(aranan, "sayisi demet icerisinde bulunamadi.")
25 sayisi demette 3 kez geciyor.
100 sayisi demette 0 kez geciyor.
25 sayisinin ilk goruldugu indeks: 1
70 sayisi demet icerisinde bulunamadi.

Paket Açma (Tuple Unpacking) Nedir?

Python'da bir demetin elemanlarını ayrı değişkenlere tek bir hamlede dağıtma işlemine paket açma (unpacking) adı verilir. Paket açma, verileri indeks numaralarıyla tek tek (örneğin kullanici[0], kullanici[1]) çekme zorunluluğunu ortadan kaldırarak kodun okunabilirliğini ve yazım hızını ciddi oranda artırır.

Temel paket açma işleminde sol tarafta tanımlanan değişken sayısı ile sağ taraftaki demetin eleman sayısı tam olarak birbirine eşit olmalıdır. Değişken ve eleman sayısı uyuşmadığında Python hata üretir.

Değişken Değerlerini Takas Etme (Swap)

Paket açma mekanizmasının programlamada sağladığı en pratik çözümlerden biri iki değişkenin değerini üçüncü bir geçici değişkene gerek duymadan birbiriyle değiştirmektir (swap). C veya Java gibi dillerde bu işlem için geçici bir temp değişkeni kullanılırken, Python'da demet paketleme ve paket açma mekanizması arka planda devreye girer.

Aşağıdaki tam kod örneğinde temel paket açma kuralını ve değişken takasını görebilirsiniz:

# Temel paket acma
kullanici = ("Ahmet", "Yilmaz", 28)
ad, soyad, yas = kullanici

print("Ad:", ad)
print("Soyad:", soyad)
print("Yas:", yas)

# Degisken degerlerini takas etme (swap)
x = 5
y = 10
print("Takas oncesi -> x:", x, "y:", y)

x, y = y, x
print("Takas sonrasi -> x:", x, "y:", y)

# Koordinat demetini degiskenlere dagitma
koordinat = (1920, 1080)
genislik, yukseklik = koordinat
print("Ekran cozunurlugu:", genislik, "x", yukseklik)
Ad: Ahmet
Soyad: Yilmaz
Yas: 28
Takas oncesi -> x: 5 y: 10
Takas sonrasi -> x: 10 y: 5
Ekran cozunurlugu: 1920 x 1080

Gelişmiş Paket Açma: Yıldız (*) İşleci

Bazı durumlarda bir demetteki tüm elemanları tek tek değişkenlere aktarmak istemeyiz veya demetin eleman sayısı önceden sabit olmayabilir. Python 3 ile birlikte sunulan genişletilmiş paket açma (extended unpacking) özelliği, değişken adının başına eklenen yıldız (*) işleci sayesinde bu gereksinimi çözer.

Yıldız işleci ile tanımlanan değişken, diğer bağımsız değişkenlere atanmayan arta kalan tüm elemanları bir liste yapısı altında toplar. Bir paket açma satırında yalnızca bir adet yıldızlı değişken bulunabilir.

Yıldız işlecinin demet içerisindeki konumuna göre sağladığı esneklikler şunlardır:

Ayrıca Python yazım standartlarında (PEP 8), paket açma sırasında ihtiyaç duyulmayan veya kullanılmayacak değerleri temsil etmek için alt tire (_) simgesi yaygın bir kural olarak tercih edilir. Örneğin ad, *_, sehir = demet yazıldığında, aradaki verilerin göz ardı edildiği açıkça belirtilmiş olur.

notlar = (85, 90, 78, 92, 88, 95)

# Ilk not, son not ve aradaki tum notlari ayirma
ilk_not, *ara_notlar, son_not = notlar

print("Ilk sinav notu:", ilk_not)
print("Son sinav notu:", son_not)
print("Ara sinavlar (liste):", ara_notlar)

# Alt tire (_) ile gereksiz degerleri goz ardi etme
personel = ("Mehmet", "Kaya", "Yazilim", "Istanbul", 2021)
ad, soyad, *_, ise_giris_yili = personel

print("Personel:", ad, soyad)
print("Ise Giris Yili:", ise_giris_yili)
Ilk sinav notu: 85
Son sinav notu: 95
Ara sinavlar (liste): [90, 78, 92, 88]
Personel: Mehmet Kaya
Ise Giris Yili: 2021

Döngülerde Paket Açma

Paket açma işlemi yalnızca doğrudan atama satırlarında değil, döngü yapılarında da sıklıkla kullanılır. Elemanları demetlerden oluşan bir liste üzerinde for döngüsü kurarken demetin elemanlarını doğrudan döngü tanımında değişkenlere ayırabiliriz.

urunler = [
    ("Klavye", 450, 15),
    ("Fare", 250, 30),
    ("Kulaklik", 700, 8)
]

print("Depo Urun Raporu:")
for urun_adi, birim_fiyat, stok_adedi in urunler:
    toplam_deger = birim_fiyat * stok_adedi
    print("- " + urun_adi + " (Birim Fiyat: " + str(birim_fiyat) + " TL, Stok: " + str(stok_adedi) + " adet) -> Toplam: " + str(toplam_deger) + " TL")
Depo Urun Raporu:
- Klavye (Birim Fiyat: 450 TL, Stok: 15 adet) -> Toplam: 6750 TL
- Fare (Birim Fiyat: 250 TL, Stok: 30 adet) -> Toplam: 7500 TL
- Kulaklik (Birim Fiyat: 700 TL, Stok: 8 adet) -> Toplam: 5600 TL

Sık Yapılan Hatalar

Alıştırma

Bir e-ticaret sisteminde sipariş kaydı aşağıdaki demet yapısıyla tutulmaktadır:

siparis = ("SP-2024-981", "Ahmet Yilmaz", 120.50, 45.00, 310.00, 99.90, "Teslim Edildi")

Bu demetin ilk elemanı sipariş kodunu, ikinci elemanı müşteri adını, son elemanı sipariş durumunu, aradaki tüm sayılar ise sipariş edilen ürünlerin fiyatlarını belirtmektedir.

Sizden beklenen adımlar:

  1. Genişletilmiş paket açma (yıldız işleci) tekniğiyle sipariş kodunu, müşteri adını, ürün fiyatlarını (ayrı bir liste olarak) ve sipariş durumunu tek satırda değişkenlere ayırın.
  2. Müşteri adını ve sipariş kodunu ekrana yazdırın.
  3. Satın alınan ürün adedini (len() ile) ve toplam ödeme tutarını (sum() ile) hesaplayıp yazdırın.
  4. Sipariş durumunu ekrana yazdırın.

Çözüm

siparis = ("SP-2024-981", "Ahmet Yilmaz", 120.50, 45.00, 310.00, 99.90, "Teslim Edildi")

# Tek satirda genisletilmis paket acma
siparis_kodu, musteri_adi, *fiyatlar, siparis_durumu = siparis

# Temel bilgileri yazdirma
print("Musteri:", musteri_adi)
print("Siparis Kodu:", siparis_kodu)

# Urun adedi ve toplam tutar hesaplama
urun_adedi = len(fiyatlar)
toplam_tutar = sum(fiyatlar)

print("Alinan Urun Adedi:", urun_adedi)
print("Toplam Tutar:", toplam_tutar, "TL")
print("Durum:", siparis_durumu)
Musteri: Ahmet Yilmaz
Siparis Kodu: SP-2024-981
Alinan Urun Adedi: 4
Toplam Tutar: 575.4 TL
Durum: Teslim Edildi

Özet

Yazının tamamını ve yorumları sitede aç