Python Dersleri #23: Demet Metotları ve Paket Açma
Uzmoon · · 7 dk
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:
ilk, *kalan = demet: İlk elemanı tek bir değişkene alır, geriye kalan tüm elemanları listeye dönüştürür.*kalan, son = demet: Son elemanı tek bir değişkene ayırır, baştaki tüm değerleri listeler.ilk, *orta, son = demet: İlk ve son elemanları ayrı değişkenlere aktarır, ortada kalan tüm elemanları bir liste olarak toplar.
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
- Değişken ve Eleman Sayısının Uyuşmaması: Paket açma işleminde sol taraftaki değişken adedi ile sağdaki demet eleman adedi birbirini tutmadığında ve yıldız (
*) işleci kullanılmadığında PythonValueError: not enough values to unpackveyaValueError: too many values to unpackhatası verir. - Birden Fazla Yıldızlı İfade Kullanmak: Tek bir atama işleminde birden fazla yıldızlı değişken kullanılamaz (örneğin
*a, *b = demet). Python hangi değişkenin kaç eleman kapsayacağını bilemeyeceğinden derleme aşamasındaSyntaxError: multiple starred expressions in assignmenthatası fırlatır. - Demette Bulunmayan Eleman İçin index() Çağırmak: Demet içerisinde yer almayan bir değer
index()ile arandığında-1değeri dönmez; doğrudanValueErroroluşur. Arama yapmadan önce elemanın varlığı denetlenmelidir. - Demetlerde Liste Değiştirme Metotları Aramak: Demetler değiştirilemez olduğu için
append(),extend(),pop()veyasort()gibi metotlara sahip değildir. Bu metotları bir demet üzerinde çağırmakAttributeErrorile sonuçlanır.
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:
- 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.
- Müşteri adını ve sipariş kodunu ekrana yazdırın.
- Satın alınan ürün adedini (
len()ile) ve toplam ödeme tutarını (sum()ile) hesaplayıp yazdırın. - 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
- Python demetleri değiştirilemez veri yapıları olduğundan yalnızca eleman saymaya yarayan
count()ve elemanın ilk indeksini döndürenindex()yerleşik metotlarına sahiptir. - Paket açma (unpacking), demet içerisindeki elemanları doğrudan ve temiz bir sözdizimiyle bağımsız değişkenlere aktarmayı sağlar.
- Gelişmiş paket açmada kullanılan yıldız (
*) işleci, sayısı değişken veya bilinmeyen ara elemanları otomatik olarak bir listede toplamaya olanak tanır. - Değişken değerlerinin takas edilmesi (swap) ve döngülerde demet listelerinin işlenmesi, paket açmanın en yaygın ve faydalı kullanım alanları arasındadır.