Sözlükler, kümeler ve koleksiyon seçimi
Listelerde bir değere erişmek için çoğunlukla indeks kullanırız. Fakat gerçek veriler çoğu zaman “0. eleman” veya “2. eleman” diye değil, ad, fiyat, stok, öğrenci numarası gibi anlamlı alanlarla düşünülür.
Bu hafta Python’ın sözlük (dict) yapısını anahtar–değer ilişkileri için, küme (set) yapısını ise tekrarsız değerleri tutmak için kullanacağız. Ayrıca “bu problem için liste mi, sözlük mü, küme mi?” sorusunu bilinçli biçimde sormaya başlayacağız.
Bu bölümün kapsamı
- anahtar–değer modeliyle okuma ve alan güncelleme
indenetiminin anahtarı aramasıget()ile varsayılan kullanmanın yararı ve bedeli.keys(),.values()ve.items()farkı- sözlük anahtarının değişmez olma zorunluluğu
- sözlükle frekans veya sayaç tablosu kurma
- kümenin benzersizlik ve sıra davranışı, koleksiyon seçimi
collectionsmodülündeki hazır sayaç yapıları- küme kesişim, birleşim ve fark işlemlerinin ayrıntısı
Bu başlıklar konunun devamıdır; ileride karşınıza çıkar ama bu derste ezberlemeniz beklenmiyor.
"Kalem" in urun neden False döndürüyor?
Sözlükte in denetimi değerlere değil anahtarlara bakar. Veriye artık konumuyla değil adıyla ulaşacaksınız; hangi problemde hangi koleksiyonun doğal olduğuna da burada karar vereceğiz.
Sözlük: anahtardan değere erişim
Bir ürün bilgisini listeyle şöyle tutmak mümkün olabilir:
urun = ["Kalem", 12.5, 40]Fakat urun[1] ifadesinin ne olduğunu anlamak için listenin düzenini bilmek gerekir.
Sözlükte alanlara ad veririz:
urun = {
"ad": "Kalem",
"fiyat": 12.5,
"stok": 40
}Değerlere anahtar ile erişiriz:
print(urun["ad"])
print(urun["fiyat"])
print(urun["stok"])Burada "ad", "fiyat" ve "stok" anahtarlardır.
Anahtar–değer ilişkisi
Sözlükte her anahtar bir değeri gösterir:
"ad" → "Kalem"
"fiyat" → 12.5
"stok" → 40
Anahtarlar benzersiz olmalıdır. Aynı anahtar yeniden atanırsa eski değer güncellenir.
urun = {"stok": 40}
urun["stok"] = 35
print(urun)Sonuç:
{'stok': 35}
Yeni alan da eklenebilir:
urun["kategori"] = "Kırtasiye"Sözlükte in anahtarı kontrol eder
Sözlük üzerinde in kullandığınızda varsayılan olarak anahtarların varlığı kontrol edilir:
urun = {"ad": "Kalem", "stok": 40}
print("stok" in urun) # True
print("fiyat" in urun) # False
print("Kalem" in urun) # FalseSon satırda "Kalem" bir değerdir, anahtar değildir. Değerler içinde arama yapılacaksa bunu ayrıca .values() ile ifade etmek gerekir:
print("Kalem" in urun.values())Bu ayrım özellikle eksik alan kontrolünde kullanışlıdır:
if "stok" in urun:
print("Stok bilgisi var")
else:
print("Stok bilgisi eksik")Tahmin et — sözlük nasıl değişir?
Aşağıdaki kodu çalıştırmadan önce çıktıyı tahmin edin:
Sözlükte alanların adla erişilebilir olması, kodun niyetini listede sabit indeks kullanmaktan daha görünür kılar.
Alıştırma — stok değerini güncelleyin
Bir satış sonrasında stoktan 3 ürün eksilsin.
Beklenen sonuç 9dur.
urun["stok"] = urun["stok"] - 3 yazabilirsiniz.
urun = {
"ad": "Defter",
"fiyat": 45,
"stok": 12
}
urun["stok"] = urun["stok"] - 3
print(urun["stok"])Eksik anahtar ve get()
Sözlükte olmayan bir anahtara köşeli parantezle erişmek KeyError üretir:
urun = {"ad": "Kalem"}
# print(urun["stok"])Eğer alanın bulunmaması normal bir durumsa get() kullanılabilir:
urun = {"ad": "Kalem"}
stok = urun.get("stok")
print(stok)Sonuç None olur.
Varsayılan değer de verebiliriz:
stok = urun.get("stok", 0)
print(stok)Bu kez sonuç 0 olur.
get("stok", 0) kullanmak her problemde doğru değildir. Eksik stok bilgisinin gerçekten 0 anlamına gelip gelmediğini problem kuralı belirler. “Veri yok” ile “değer gerçekten sıfır” aynı bilgi değildir.
Sözlük üzerinde gezinmek: keys(), values(), items()
Bir sözlüğün üç yaygın görünümü vardır:
urun = {"ad": "Kalem", "fiyat": 12.5, "stok": 40}
print(urun.keys())
print(urun.values())
print(urun.items()).keys()→ anahtarları,.values()→ değerleri,.items()→(anahtar, deger)çiftlerini
sunar.
Yalnızca anahtarlar üzerinde dolaşırken şu iki kullanım eşdeğer niyettedir:
for anahtar in urun:
print(anahtar)for anahtar in urun.keys():
print(anahtar)Yalnızca değerleri istiyorsak:
for deger in urun.values():
print(deger)Anahtar ve değeri birlikte almak için:
for anahtar, deger in urun.items():
print(anahtar, deger)items() her adımda iki elemanlı bir demet verir; 9. haftadaki demet açma bilgimizi burada yeniden kullanıyoruz.
Sözlükten kayıt silmek
Bir anahtar–değer çiftini silmek için pop() kullanışlıdır:
urun = {"ad": "Kalem", "stok": 40, "gecici_not": "kontrol"}
silinen = urun.pop("gecici_not")
print(silinen)
print(urun)pop() anahtarı siler ve silinen değeri döndürür. Anahtarın bulunmaması normal bir olasılıksa varsayılan verebilirsiniz:
silinen = urun.pop("indirim", None)del urun["stok"] sözdizimi de anahtarı silebilir; ancak olmayan anahtarda KeyError üretir. Başlangıçta silinen değere de ihtiyaç duyduğumuz örneklerde pop() daha açıklayıcıdır.
Hangi değerler sözlük anahtarı olabilir?
Sözlük, anahtarı hızlı biçimde bulmak için anahtarın hashlenebilir (hashable) olmasını ister. Başlangıç düzeyinde pratik kural şudur: anahtar olarak çoğunlukla değiştirilemeyen değerler kullanın.
Yaygın geçerli anahtarlar:
kayit = {
"ad": "Deniz", # str
101: "aktif", # int
(41, 36): "nokta" # tuple içindeki elemanlar da hashlenebilirse
}Liste değiştirilebilir olduğu için sözlük anahtarı olamaz:
sozluk = {}
# sozluk[[1, 2]] = "x"
# TypeError: unhashable type: 'list'Bu davranışı 9. haftadaki mutable / immutable ayrımıyla ilişkilendirebilirsiniz.
“Her değiştirilemez değer mutlaka her durumda iyi anahtardır” gibi ezber bir sonuç çıkarmayın. Buradaki temel fikir, sözlük anahtarının sözlük içindeyken güvenilir biçimde bulunabilir bir kimlik sağlamasıdır. Bu ders için str, int ve basit uygun demetler yeterlidir.
Sözlük sırası ile küme sırası aynı değildir
Modern Python’da (3.7+) sözlükler anahtarların eklenme sırasını korur:
urun = {}
urun["ad"] = "Kalem"
urun["fiyat"] = 12.5
urun["stok"] = 40
print(list(urun.keys()))Bu program anahtarları ekleme sırasıyla verir:
['ad', 'fiyat', 'stok']
Ancak bu, sözlüğün anahtarları alfabetik veya sayısal olarak sıraladığı anlamına gelmez. Yalnızca ekleme sırası korunur.
Kümelerde ise gösterim veya dolaşma sırasına güvenilmemelidir. Aynı küme farklı çalıştırma veya ortamlarda farklı sırada görünebilir.
Bir alıştırmada kümenin elemanlarını farklı sırada görmeniz tek başına cevabınızın yanlış olduğu anlamına gelmez. Kümede önemli olan üyelik ve benzersizliktir. Belirli bir çıktı sırası gerekiyorsa sorted(kume) gibi açık bir sıralama adımı kullanın.
Sayma tablosu oluşturmak
Sözlüklerin güçlü kullanım alanlarından biri frekans sayımıdır.
Bir listedeki şehirlerin kaç kez geçtiğini bulalım:
sehirler = ["Samsun", "Ordu", "Samsun", "Amasya", "Ordu", "Samsun"]
sayilar = {}
for sehir in sehirler:
sayilar[sehir] = sayilar.get(sehir, 0) + 1
print(sayilar)Sonuç:
{'Samsun': 3, 'Ordu': 2, 'Amasya': 1}
Her şehir ilk kez görüldüğünde get(sehir, 0) değeri 0 verir; sonraki karşılaşmalarda mevcut sayı alınır ve bir artırılır.
Alıştırma — durumları sayın
Aşağıdaki listede "tamam" ve "bekliyor" değerlerinin kaç kez geçtiğini sözlükte sayın.
Beklenen:
{'tamam': 3, 'bekliyor': 2}
get(durum, 0) mevcut sayıyı veya ilk karşılaşmada sıfırı verir.
durumlar = ["tamam", "bekliyor", "tamam", "tamam", "bekliyor"]
sayilar = {}
for durum in durumlar:
sayilar[durum] = sayilar.get(durum, 0) + 1
print(sayilar)Küme (set): tekrarsız değerler
Bir küme her değeri bir kez tutar:
etiketler = {"python", "web", "python", "veri"}
print(etiketler)Kümede "python" yalnızca bir kez bulunur. Fakat ekrana hangi sırada yazılacağı sözlükteki ekleme sırası davranışı gibi garanti edilmez.
Bir listeyi kümeye dönüştürmek de mümkündür:
sehirler = ["Samsun", "Ordu", "Samsun", "Amasya"]
benzersiz = set(sehirler)
print(benzersiz)Küme, benzersiz değerleri bulmak istediğimizde kullanışlıdır.
Kümeyi indeksle sıralı bir yapı gibi kullanmayın. kume[0] biçiminde erişim yoktur. Eğer sıra problem için önemliyse liste daha uygun olabilir.
Kümede üyelik kontrolü
Kümeler üyelik kontrolü için doğal bir yapıdır:
izinli_roller = {"ogrenci", "personel", "misafir"}
rol = "personel"
if rol in izinli_roller:
print("Rol tanımlı")Eleman eklemek için add():
izinli_roller.add("yonetici")Tahmin et — kaç benzersiz değer var?
İlk uzunluk 6, benzersiz değer sayısı 4 olur.
Alıştırma — tekrar eden kayıtları azaltın
Aşağıdaki ders kodlarından benzersiz olanları küme olarak elde edin.
Beklenen benzersiz değer sayısı 3tür. Kümenin ekrana hangi sırada yazıldığı değerlendirme ölçütü değildir.
set(dersler) listedeki tekrarları kaldırarak küme üretir.
dersler = ["BLP101", "BLP102", "BLP101", "BLP103", "BLP102"]
benzersiz_dersler = set(dersler)
print(benzersiz_dersler)
print(len(benzersiz_dersler))Hangi koleksiyonu seçmeliyim?
Tek bir “en iyi” koleksiyon yoktur. Veriyle ne yapmak istediğimiz önemlidir.
| İhtiyaç | Genellikle uygun yapı |
|---|---|
| Sıralı bir değer dizisi | list |
| Küçük ve değişmemesi beklenen sıralı grup | tuple |
| Anlamlı anahtardan değere erişim | dict |
| Tekrarsız değerler ve üyelik kontrolü | set |
Örnekler:
- Bir öğrencinin haftalık puanları → liste
- Bir koordinat çifti → demet
- Bir ürünün
ad,fiyat,stokalanları → sözlük - Sistemde görülen benzersiz hata kodları → küme
Koleksiyonu verinin “nasıl göründüğüne” göre değil, programın veriye nasıl erişeceğine ve ne yapacağına göre seçin.
Liste ve sözlüğü birlikte kullanmak
Birden fazla ürün kaydı tutmak için her ürünü sözlük, kayıtların tamamını liste yapabiliriz:
urunler = [
{"ad": "Kalem", "fiyat": 12.5},
{"ad": "Defter", "fiyat": 45},
{"ad": "Silgi", "fiyat": 8}
]
for urun in urunler:
print(urun["ad"], urun["fiyat"])Bu yapı gelecek haftanın ana konusudur: birden fazla kayıt üzerinde filtreleme, gruplama ve özetleme.
Üret — basit stok özeti
Bir stok sözlüğünde ürün kodları anahtar, stok miktarları değer olsun:
stoklar = {
"KLM": 12,
"DFT": 0,
"SLG": 8,
"CTN": 0
}stok_ozeti(stoklar) adlı fonksiyon:
- Toplam stok miktarını,
- Stoku
0olan ürün sayısını
hesaplayıp (toplam_stok, tukenen_urun_sayisi) demeti olarak döndürsün.
Başlangıç:
Beklenen:
(20, 2)
for miktar in stoklar.values(): biçiminde değerler üzerinde gezinebilirsiniz.
def stok_ozeti(stoklar):
toplam_stok = 0
tukenen_urun_sayisi = 0
for miktar in stoklar.values():
toplam_stok = toplam_stok + miktar
if miktar == 0:
tukenen_urun_sayisi = tukenen_urun_sayisi + 1
return toplam_stok, tukenen_urun_sayisi
stoklar = {
"KLM": 12,
"DFT": 0,
"SLG": 8,
"CTN": 0
}
print(stok_ozeti(stoklar))Tek sayfa özet
Bu hafta koleksiyon seçimimizi problem ihtiyacına göre genişlettik.
- Sözlük anahtar–değer ilişkileri tutar.
sozluk["anahtar"]değere doğrudan erişir;"anahtar" in sozlukanahtarın bulunup bulunmadığını kontrol eder.- Bir anahtara yeniden atama yapmak değeri günceller;
pop()veyadelile alan silinebilir. get()eksik anahtarda varsayılan değer kullanmaya izin verir..keys(),.values()ve.items()sırasıyla anahtar, değer ve anahtar–değer çiftlerini dolaşmayı sağlar.- Sözlük anahtarları hashlenebilir olmalıdır; değiştirilebilir
listanahtar olamaz. - Python 3.7+ sözlükler ekleme sırasını korur; bu alfabetik sıralama anlamına gelmez.
- Sözlük, frekans veya sayaç tablosu oluşturmak için uygundur.
- Küme tekrarsız değerler tutar ve sıralı indeks yapısı değildir; yazdırma/dolaşma sırasına güvenilmez.
set(liste)benzersiz değerleri elde etmek için kullanılabilir.in, kümede üyelik kontrolü için doğal bir işlemdir.- Liste, demet, sözlük ve küme farklı erişim ihtiyaçlarına hizmet eder.
Bir sonraki bölümde liste ve sözlükleri birlikte kullanarak küçük kayıt kümelerini işleyeceğiz.
Bu bölümün kazanımları
Bu bölümü bitiren öğrenci:
- Anahtar–değer modeliyle sözlükten değer okur ve alan günceller.
indenetiminin sözlükte değeri değil anahtarı aradığını bilir.get()ile eksik anahtarda varsayılan kullanır ve bunun bedelini açıklar..keys(),.values()ve.items()arasındaki farkı ayırır.- Sözlük anahtarının hashlenebilir olması gerektiğini açıklar.
- Sözlükle frekans veya sayaç tablosu kurar.
- Kümenin benzersizlik ve sıra davranışını tanır ve probleme uygun koleksiyonu seçer.