Python Programlama Dili

6. Sözlükler

Bu bölümde Python’daki en verimli ve en kullanışlı veri tiplerinden birini inceleyeceğiz. Bölümümüzün konusu sözlükler. Sözlükler Python’un bir hayli güçlü araçlarından bir tanesidir. O kadar ki, istersek sözlükleri basit bir veritabanı niyetine bile kullanabiliriz.

Şimdiye kadar şu veri tiplerini görmüştük:

  1. Karakter Dizileri
  2. Sayılar
  3. Listeler
  4. Demetler

Şimdi ise bunlara bir de sözlükleri ekleyeceğiz. Sözlükler şekil olarak öteki veri tiplerinden birazcık farklı bir görünüme sahiptir. Ayrıca mesela listeler “sıralı diziler” (ordered sequence) şeklinde tanımlanan bir gruba girerken, sözlükler “sırasız diziler” (unordered sequence) grubuna dahildir. Burada sıralı-sırasız kavramlarıyla kastettiğimiz şeyin ne olduğunu asıl konumuza geçtiğimizde öğreneceğiz.

İsterseniz lafı daha fazla dolandırmadan asıl mevzuya geçelim. Ben sizin, sözlükleri öğrendikten sonra bu veri tipini çok seveceğinize eminim...

6.1. Sözlükleri Tanımlamak

Öteki veri tiplerinde yaptığımız gibi, sözlüklerle de ilk işimiz bunları tanımlamak olacaktır. Hatırlarsanız listelerin ve demetlerin birtakım ayırt edici işaretleri vardı. Mesela listelerin ayırt edici işareti “[]” iken, demetlerin ayırt edici işareti ise “()” idi... Tıpkı listeler ve demetlerde olduğu gibi, sözlüklerin de bir ayırt edici işareti vardır:

>>> ilk_sözlük = {}

Gördüğünüz gibi, sözlükleri küme parantezleri yardımıyla öteki veri tiplerinden ayırt ediyoruz. Yukarıda boş bir sözlük tanımladık. Pythonca’da sözlükler “dict” parçacığıyla gösterilir. Gelin isterseniz basit bir tip denetlemesi yapalım:

>>> type({})

<class 'dict'>

Buradaki “dict” sözcüğü denetlediğimiz veri tipinin bir sözlük olduğuna işaret ediyor.

Şimdi boş bir sözlük yerine, içinde öğe barındıran bir sözlük tanımlamaya çalışalım:

>>> telefonlar = {"Ahmet": "0555 555 55 55", "Ayşe": "0212 212 12 12",
... "Veli": "0312 312 13 13"}

Burada sözlüğü nasıl tanımladığımıza çok dikkat edin. Dediğimiz gibi, sözlüklerin yapısı öteki veri tiplerinden biraz farklıdır. İsterseniz yukarıda tanımladığımız sözlüğü biraz sadeleştirerek incelemeyi kolaylaştıralım:

>>> telefonlar = {"Ahmet": "0555 555 55 55"}

Burada şöyle bir yapı gözümüze çarpıyor:

{anahtar: değer}

Bu yapıda “anahtar” ve “değer” kelimelerini kullanmamız tesadüfi değildir. Python programlama dilinde sözlükler bir “anahtar-değer” (key-value) çifti olarak tanımlanır. Yani her sözlükte en az bir anahtar, bir de değer bulunur. Sözlükleri oluştururken bu anahtar ve değerleri iki nokta üst üste işareti (“:”) ile ayırırız. Bizim örneğimizde anahtara karşılık gelen ifade “Ahmet”; değere karşılık gelen ifade ise “0555 555 55 55”tir. Sözlüklerin öğelerine ulaşmak için anahtarları kullanacağız. Bu açıklamaların biraz soyut gelebileceğini düşünerek, durumu somutlaştırmak için bir örnek verelim. Yukarıdaki sözlük üzerinden gidelim. Sözlüğümüzdeki “Ahmet” adlı anahtarın değerini alalım:

>>> telefonlar["Ahmet"]

'0555 555 55 55'

Gördüğünüz gibi, ortada listeler ve demetlere göre farklı bir durum var. Bir sözlüğün öğelerine ulaşma biçimimiz, demetler ve listelerdeki yapıdan farklı. Hatırlarsanız demetler ve listelerin öğelerine şöyle ulaşıyorduk:

liste[öğenin_sıra_numarası]

...veya...

demet[öğenin_sıra_numarası]

Listeler ve demetlerde, öğeye ulaşmak için o öğenin sıra numarasını verirken, sözlüklerde ise anahtarını kullanıyoruz. Çıktıda elde ettiğimiz şey ise o anahtarın değeri oluyor... Yani “Ahmet” anahtarını vererek, “0555 555 55 55” değerine ulaşıyoruz.

Hatırlarsanız giriş bölümünde sözlüklerin sırasız bir veri tipi olduğundan söz etmiştik. Sözlüklerin sırasız olmasından dolayı, öğelere erişmek için sıra numarası kullanamıyoruz. Sözlüklerin aksine listeler ve demetler sıralı birer veri tipi olduğu için, öğelere sıra numarasıyla ulaşabiliyoruz.

Sözlüklerin sırasız bir veri tipi olması kendini çıktıda da gösterecektir. Yani bir sözlüğü tanımladıktan sonra, o sözlüğü ekrana yazdırdığımızda elde ettiğimiz çıktı öğelerin sırası bakımından karışık olacaktır... Mesela şu sözlüğü ele alalım:

>>> harfler = {"a": 1, "b": 2, "c": 3}

Bu sözlüğü ekrana yazdırdığımızda şöyle bir çıktı alırız:

>>> harfler

{'a': 1, 'c': 3, 'b': 2}

Gördüğünüz gibi elde ettiğimiz çıktıda öğelerin sıralaması sözlüğü tanımlarken kullandığımız öğe sıralamasından farklı... Eğer tanımladığınız bir sözlükteki öğelerin sıralaması çıktıdakiyle aynıysa bu durum tamamen tesadüften ibarettir. Sözlükler sırasız veri tipleri olduğu için, sözlüklerle güvenli bir şekilde sıralamaya dayalı herhangi bir işlem yapamayız...

Sözlükleri tanımlamanın başka yolları da vardır. Yukarıdaki tanımlama yönteminin dışında bir de şöyle bir şey yapabiliriz:

>>> giyim = {}

>>> giyim["ayakkabı"] = 2
>>> giyim["elbise"] = 1
>>> giyim["gömlek"] = 4

>>> giyim

{'elbise': 1, 'ayakkabı': 2, 'gömlek': 4}

Gördüğünüz gibi, önce boş bir sözlük tanımladıktan sonra bu boş sözlüğe daha sonradan teker teker öğe ekleyebiliyoruz.

Eğer istersek üçüncü bir yol olarak sözlükleri “dict” parçacığını kullanarak da tanımlayabiliriz:

>>> dict({"a": 1, "b": 2})

Bu “dict” parçacığını farklı şekillerde de kullanabiliyoruz:

>>> dict(ahmet = "0533 344 44 44")

Burada da sanki bir değişken tanımlar gibi sözlük tanımladığımıza dikkat edin...

Bunun dışında, demetler ve listeleri kullanarak da bir sözlük tanımlayabiliriz:

>>> dict([("ahmet", "0533 444 44 44")])

Burada iki öğeli bir demetten oluşan bir listeyi “dict” parçacığı yardımıyla sözlüğe dönüştürüyoruz...

Gördüğünüz gibi, sözlük tanımlamak için pek çok farklı yöntem bulunuyor. Siz bunlar içinde kolayınıza geleni veya o an karşı karşıya olduğunuz duruma en uygun yöntemi benimseyeceksiniz...

6.2. Sözlüklerin Metotları

Sözlükler değiştirilebilir veri tipleridir. Dolayısıyla sözlükler metot sayısı bakımından zengin sayılır. Sözlüklerin hangi metotlara sahip olduğunu nasıl öğreneceğimizi az çok tahmin ediyorsunuzdur. Daha önce liste ve demet veri tiplerini incelerken birkaç farklı şekilde, bu veri tiplerinin sahip olduğu metotları listelemeyi öğrenmiştik. Sözlükler de benzer yöntemlerle bize metotlarını listeleme imkanı sunar. Mesela şöyle bir şey yapabiliriz:

>>> dir(dict)

['__class__', '__contains__', '__delattr__', '__delitem__', '__doc__',
 '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__',
 '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__',
 '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
 '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__',
 '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items',
 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

Her zaman olduğu gibi, bu liste içinde bizim ilgileneceğimiz metotlar şunlardır:

>>> for i in dir(dict):
...     if "_" not in i:
...         print(i)
...
clear
copy
fromkeys
get
items
keys
pop
popitem
setdefault
update
values

Gördüğünüz gibi sözlüklerin 11 adet metodu var bizim ilgilendiğimiz... Sonraki sayfalarda bu metotları tek tek inceleyeceğiz. Yalnız, dikkat ederseniz yukarıdaki listeyi elde etmek için çok fazla uğraşıyoruz. İlerde kodlarımızı belli ölçütlere göre süzmek istediğimiz zaman bu isteğimizi tek satırla yerine getirmeyi de öğreneceğiz:

>>> [i for i in dir(dict) if "_" not in i]

['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem',
'setdefault', 'update', 'values']

Python’da bu yapıya “liste üreteçleri” (list comprehensions) adı verilir. Yeri geldiğinde bu konuyu da ayrıntısıyla inceleyeceğiz. Şimdilik sadece böyle bir imkanımızın olduğunu da bilelim yeter...

Neyse... Tekrar konumuza dönelim. Sözlüklerin 11 adet metodu varmış. İsterseniz lafı hiç uzatmadan ilk metodumuzu incelemeye başlayalım...

6.2.1. clear metodu

Sözlüklerin, inceleyeceğimiz ilk metodu clear(). Bu kelime İngilizce’de “temizlemek” anlamına gelir. Görevi sözlükteki öğeleri temizlemektir. Yani içi dolu bir sözlüğü bu metot yardımıyla tamamen boşaltabiliriz:

>>> lig = {"şampiyon": "Adana Demirspor", "ikinci": "Mersin İdman Yurdu",
... "üçüncü": "Adana Gençlerbirliği"}

İsterseniz sözlüğümüzü boşaltmadan önce bu sözlükle biraz çalışalım:

Sözlüğümüzün öğelerine şöyle ulaşıyoruz:

>>> lig

{'şampiyon': 'Adana Demirspor', 'ikinci': 'Mersin İdman Yurdu',
 'üçüncü': 'Adana Gençlerbirliği'}

Eğer bu sözlüğün öğelerine tek tek erişmek istersek şöyle yapıyoruz:

>>> lig["şampiyon"]

'Adana Demirspor'

>>> lig["üçüncü"]

'Adana Gençlerbirliği'

Şimdi geldi bu sözlüğün bütün öğelerini silmeye:

>>> lig.clear()

Şimdi sözlüğümüzün durumunu tekrar kontrol edelim:

>>> lig

{}

Gördüğünüz gibi artık “lig” adlı sözlüğümüz bomboş. clear() metodunu kullanarak bu sözlüğün bütün öğelerini sildik. Ama tabii ki bu şekilde sözlüğü silmiş olmadık. Boş da olsa bellekte hâlâ “lig” adlı bir sözlük duruyor. Eğer siz “lig”i ortadan kaldırmak isterseniz “del” adlı bir parçacıktan yararlanmanız gerekir:

>>> del lig

Kontrol edelim:

>>> lig

NameError: name 'lig' is not defined

Gördüğünüz gibi artık “lig” diye bir şey yok... Bu sözlüğü bellekten tamamen kaldırdık.

clear() adlı metodun ne olduğunu ve ne işe yaradığını gördüğümüze göre başka bir metoda geçebiliriz.

6.2.2. copy metodu

Diyelim ki elimizde şöyle bir sözlük var:

>>> hava_durumu = {"İstanbul": "yağmurlu", "Adana": "güneşli",
... "İzmir": "bulutlu"}

Biz bu sözlüğü kopyalamak istiyoruz. Hemen şöyle bir şey deneyelim:

>>> yedek_hava_durumu = hava_durumu

Artık elimizde aynı sözlükten iki tane var:

>>> hava_durumu

{'İstanbul': 'yağmurlu', 'Adana': 'güneşli', 'İzmir': 'bulutlu'}

>>> yedek_hava_durumu

{'İstanbul': 'yağmurlu', 'Adana': 'güneşli', 'İzmir': 'bulutlu'}

Şimdi hava_durumu adlı sözlüğe bir öğe ekleyelim:

>>> hava_durumu["Mersin"] = "sisli"

>>> hava_durumu

{'İstanbul': 'yağmurlu', 'Adana': 'güneşli', 'Mersin': 'sisli',
 'İzmir': 'bulutlu'}

Şimdi bir de yedek_hava_durumu adlı sözlüğün durumuna bakalım:

>>> yedek_hava_durumu

{'İstanbul': 'yağmurlu', 'Adana': 'güneşli', 'Mersin': 'sisli',
 'İzmir': 'bulutlu'}

Gördüğünüz gibi, hava_durumu adlı sözlüğe yaptığımız ekleme yedek_hava_durumu adlı sözlüğü de etkiledi. Hatırlarsanız buna benzer bir durumla daha önce listeleri anlatırken de karşılaşmıştık. Çünkü varolan bir sözlüğü veya listeyi başka bir değişkene atadığımızda aslında yaptığımız şey bir kopyalama işleminden ziyade bellekteki aynı nesneye gönderme yapan iki farklı isim belirlemekten ibaret. Yani sözlüğümüzü bellekteki bir nesne olarak düşünürsek, bu nesneye atıfta bulunan, “hava_durumu” ve “yedek_hava_durumu” adlı iki farklı isim belirlemiş oluyoruz. Eğer istediğimiz şey bellekteki nesneden iki adet oluşturmak ve bu iki farklı nesneyi iki farklı isimle adlandırmak ise yukarıdaki yöntemi kullanmak istemediğiniz sonuçlar doğurabilir. Yani amacınız bir sözlüğü yedekleyip orijinal sözlüğü korumaksa ve yukarıdaki yöntemi kullandıysanız, hiç farkında olmadan orijinal sözlüğü de değiştirebilirsiniz. İşte böyle durumlarda imdadımıza sözlüklerin “copy” metodu yetişecek. Bu metodu kullanarak varolan bir sözlüğü gerçek anlamda kopyalayabilir, yani yedekleyebiliriz...

>>> hava_durumu = {"İstanbul": "yağmurlu", "Adana": "güneşli",
... "İzmir": "bulutlu"}

Şimdi bu sözlüğü yedekliyoruz. Yani kopyalıyoruz:

>>> yedek_hava_durumu = hava_durumu.copy()

Bakalım hava_durumu adlı sözlüğe ekleme yapınca yedek_hava_durumu adlı sözlüğün durumu ne oluyor?

>>> hava_durumu["Mersin"] = "sisli"

>>> hava_durumu

{'İstanbul': 'yağmurlu', 'Adana': 'güneşli', 'Mersin': 'sisli',
 'İzmir': 'bulutlu'}

yedek_hava_durumu adlı sözlüğe bakalım:

>>> yedek_hava_durumu

{'İstanbul': 'yağmurlu', 'Adana': 'güneşli', 'İzmir': 'bulutlu'}

Gördüğünüz gibi bu defa sözlüklerin birinde yapılan değişiklik öbürünü etkilemedi... copy metodu sağolsun!...

6.2.3. fromkeys metodu

fromkeys() metodu öteki metotlardan biraz farklıdır. Bu metot mevcut sözlük üzerinde işlem yapmaz. fromkeys()‘in görevi yeni bir sözlük oluşturmaktır. Bu metot yeni bir sözlük oluştururken listeler veya demetlerden yararlanır. Şöyle ki:

>>> elemanlar = "Ahmet", "Mehmet", "Can"

>>> adresler = dict.fromkeys(elemanlar, "Kadıköy")

>>> adresler

{'Ahmet': 'Kadıköy', 'Mehmet': 'Kadıköy', 'Can': 'Kadıköy'}

Gördüğünüz gibi öncelikle “elemanlar” adlı bir demet tanımladık. Daha sonra da “adresler” adlı bir sözlük tanımlayarak, fromkeys() metodu yardımıyla anahtar olarak “elemanlar” demetindeki öğelerden oluşan, değer olarak ise “Kadıköy”ü içeren bir sözlük meydana getirdik.

En başta tanımladığımız “elemanlar” demeti liste de olabilirdi. Hatta tek başına bir karakter dizisi dahi yazabilirdik oraya...

6.2.4. get metodu

Sözlük metotları içinde en faydalı metotlardan birisi bu get()`` adlı metottur. Bu metot pek çok durumda işinizi bir hayli kolaylaştırır.

Diyelim ki şöyle bir program yazdık:

#!/usr/bin/env python3.0

ing_sözlük = {"dil": "language", "bilgisayar": "computer", "masa": "table"}

sorgu = input("Lütfen anlamını öğrenmek istediğiniz kelimeyi yazınız:")

print(ing_sözlük[sorgu])

Bu programı çalıştırdığımızda eğer kullanıcı “ing_sözlük” adıyla belirttiğimiz sözlük içinde bulunan kelimelerden birini yazarsa, o kelimenin karşılığını alacaktır. Diyelim ki kullanıcımız soruya “dil” diye cevap verdi. Bu durumda ekrana “dil” kelimesinin sözlükteki karşılığı olan “language” yazdırılacaktır. Peki ya kullanıcı sözlükte tanımlı olmayan bir kelime yazarsa ne olacak? Öyle bir durumda programımız hata verecektir. Programımız için doğru yol, hata vermektense, kullanıcıyı kelimenin sözlükte olmadığı konusunda bilgilendirmektir. Bunu klasik bir yaklaşımla şu şekilde yapabiliriz:

ing_sözlük = {"dil": "language", "bilgisayar": "computer", "masa": "table"}

sorgu = input("Lütfen anlamını öğrenmek istediğiniz kelimeyi yazınız:")

if sorgu not in ing_sözlük:
    print("Bu kelime veritabanımızda yoktur!")

else:
    print(ing_sözlük[sorgu])

Ama açıkçası bu pek verimli bir yaklaşım sayılmaz. Yukarıdaki yöntem yerine sözlüklerin get() metodundan faydalanabiliriz. Bakalım bunu nasıl yapıyoruz:

ing_sözlük = {"dil": "language", "bilgisayar": "computer", "masa": "table"}

sorgu = input("Lütfen anlamını öğrenmek istediğiniz kelimeyi yazınız:")

print(ing_sözlük.get(sorgu, "Bu kelime veritabanımızda yoktur!"))

Gördüğünüz gibi, burada çok basit bir metot yardımıyla bütün dertlerimizi hallettik. Sözlüklerin get() adlı metodu, parantez içinde iki adet argüman alır. Birinci argüman sorgulamak istediğimiz sözlük öğesidir. İkinci argüman ise bu öğenin sözlükte bulunmadığı durumda kullanıcıya hangi mesajın gösterileceğini belirtir. Buna göre, yukarıda yaptığımız şey, önce “sorgu” değişkenini sözlükte aramak, eğer bu öğe sözlükte bulunamıyorsa da kullanıcıya, “Bu kelime veritabanımızda yoktur!” cümlesini göstermekten ibarettir...

Gelin isterseniz bununla ilgili bir örnek daha yapalım.

Diyelim ki bir havadurumu programı yazmak istiyoruz. Bu programda kullanıcı bir şehir adı girecek. Program da girilen şehre ait havadurumu bilgilerini ekrana yazdıracak. Bu programı klasik yöntemle şu şekilde yazabiliriz:

#!/usr/bin/env python3.0

soru = input("Şehrinizin adını tamamı küçük harf olacak şekilde yazın:")

if soru == "istanbul":
    print("gök gürültülü ve sağanak yağışlı")

elif soru == "ankara":
    print("açık ve güneşli")

elif soru == "izmir":
    print("bulutlu")

else:
    print("Bu şehre ilişkin havadurumu bilgisi bulunmamaktadır.")

Yukarıdaki, gayet geçerli bir yöntemdir. Ama biz istersek bu kodları “get” metodu yardımıyla çok daha verimli ve sade bir hale getirebiliriz:

#!/usr/bin/env python3.0

soru = input("Şehrinizin adını tamamı küçük harf olacak şekilde yazın:")

cevap = {"istanbul": "gök gürültülü ve sağanak yağışlı",
         "ankara": "açık ve güneşli", "izmir": "bulutlu"}

print(cevap.get(soru,"Bu şehre ilişkin havadurumu bilgisi bulunmamaktadır."))

Böylelikle bir metodu daha geride bıraktık... Gelelim sıradaki metodumuza...

6.2.5. items metodu

Bu metot yardımıyla bir sözlüğün bütün öğelerine ulaşabiliriz. Yalnız bu metot bir sözlüğün öğelerini doğrudan vermez. items() metodunu yalın bir şekilde kullandığımızda elde ettiğimiz şeye Python dilinde “görünüm nesnesi” (view object) adı verilir. Örnek verelim:

>>> sepet = {"meyveler": ("elma", "armut"), "sebzeler": ("pırasa", "fasulye")}

>>> sepet.items()

<dict_items object at 0xb7cee95c>

İşte burada elde ettiğimiz çıktıya “görünüm nesnesi” adı veriyorlar. Bu nesneler dinamik bir yapıdadır. Peki bu ne anlama geliyor? Hemen bakalım:

>>> a = sepet.items()

>>> len(a)

2

Buradan, sepet sözlüğündeki öğe sayısının iki olduğunu görüyoruz. Şimdi sepet sözlüğüne ekleme yapalım:

>>> sepet["içecekler"] = ("su", "ayran", "şalgam")

Şimdi “a” adlı değişkenin uzunluğunu tekrar kontrol edelim:

>>> len(a)

3

Gördüğünüz gibi, sepet adlı sözlüğün içeriği değişince “sepet.items()” metodunun içeriği de otomatik olarak güncellendi. Bu, Python 3.0’la gelen bir özelliktir. Python’un 2.x sürümlerinde items() metodu daha farklı bir yapıya sahipti ve yukarıdaki gibi otomatik güncellenme gibi bir özellik de taşımıyordu...

Peki biz bu items() metoduyla elde ettiğimiz öğeleri nasıl göreceğiz? Bunun birkaç yolu vardır. En basitinden bu metot üzerinde bir döngü kurabiliriz:

>>> for i in sepet.items():
...     print(i)
...
('içecekler', ('su', 'ayran', 'şalgam'))
('meyveler', ('elma', 'armut'))
('sebzeler', ('pırasa', 'fasulye'))

Veya list() ya da tuple() metotlarını kullanarak da sepet.items() metodunun içeriğini görebiliriz:

>>> list(sepet.items())

>>> tuple(sepet.items())

Hatırlarsanız bu yöntemi daha önce range() fonksiyonuyla birlikte de kullanmıştık...

6.2.6. keys metodu

Bir önceki bölümde incelediğimiz items() metodu bir sözlüğün bütün öğelerini almamızı sağlıyordu. Bu bölümde göreceğimiz keys() metodu ise bir sözlüğün yalnızca anahtarlarını almamımızı sağlayacak. Bu metot da tıpkı items() metodu gibi yalın olarak kullanıldığında bir görünüm nesnesi verir. Elde edilen bu görünüm nesnesi de tıpkı items() metoduyla elde ettiğimiz görünüm nesnesi gibi dinamik yapıdadır. Yani sözlüğün anahtarlarında bir değişiklik olduğunda bu görünüm nesnesi de otomatik olarak güncellenir. Şimdi bu keys() metodunu nasıl kullanacağımıza bakalım. Daha önce tanımlamış olduğumuz sepet sözlüğü üzerinden gidelim isterseniz:

>>> sepet = {"meyveler": ("elma", "armut"), "sebzeler": ("pırasa", "fasülye")}

Şimdi bu sözlükteki anahtarları alalım:

>>> anahtarlar = sepet.keys()

Şimdi de bu öğeleri ekrana yazdıralım:

>>> list(anahtarlar)

['meyveler', 'sebzeler']

Eğer anahtarları liste olarak değil de demet olarak almak istersek şu komutu kullanacağız:

>>> tuple(anahtarlar)

('meyveler', 'sebzeler')

Alternatif olarak, sepet.keys() metodu üzerinde bir for döngüsü kurmayı da tercih edebiliriz. Bu şekilde elde ettiğimiz çıktı görünüş olarak biraz daha temiz olacaktır:

>>> for i in sepet.keys():
...     print(i)
...
meyveler
sebzeler

Gördüğünüz gibi keys() metodunu kullanmak da oldukça kolaydır.

6.2.7. values metodu

Bu metot, bir önceki bölümde gördüğümüz keys() metodunun yaptığı işin tam tersini yapar. keys() metoduyla bir sözlüğün anahtarlarını alıyorduk. values() metoduyla ise sözlüğün değerlerini alacağız:

>>> sepet = {"meyveler": ("elma", "armut"), "sebzeler": ("pırasa", "fasulye")}

>>> degerler = sepet.values()

>>> for i in degerler:
...     print(i)
...
('elma', 'armut')
('pirasa', 'fasulye')

6.2.8. pop metodu

Bu metodu listelerden hatırlıyoruz. Bu metot listelerle birlikte kullanıldığında, listenin en son öğesini silip, silinen öğeyi de ekrana basıyordu. Eğer bu metodu bir sıra numarası ile birlikte kullanırsak, listede o sıra numarasına karşılık gelen öğe siliniyor ve silinen bu öğe ekrana basılıyordu. Bu metodun sözlüklerdeki kullanımı da az çok buna benzer. Ama burada farkı olarak, pop metodunu argümansız bir şekilde kullanamıyoruz. Yani pop metodunun parantezi içinde mutlaka bir sözlük öğesi belirtmeliyiz:

>>> sepet = {"meyveler": ("elma", "armut"), "sebzeler": ("pırasa", "fasulye"),
... "içecekler": ("su", "kola", "ayran")}

>>> sepet.pop("meyveler")

Bu komut, sözlükteki “meyveler” anahtarını silecek ve sildiği bu öğenin değerini ekrana basacaktır. Eğer silmeye çalıştığımız anahtar sözlükte yoksa Python bize bir hata mesajı gösterecektir:

>>> sepet.pop("tatlılar")

KeyError: 'tatlilar'

Bir program yazarken böyle bir durumla karşılaşmak istemeyiz çoğu zaman. Yani bir sözlük içinde arama yaparken, aranan öğenin sözlükte bulunmadığı bir durumda kullanıcıya mekanik ve anlamsız bir hata göstermek yerine, daha anlaşılır bir mesaj iletmeyi tercih edebiliriz. Hatırlarsanız sözlüklerin get() metodunu kullanarak benzer bir şey yapabiliyorduk. Şu anda incelemekte olduğumuz pop() metodu da bize böyle bir imkan verir. Bakalım:

>>> sepet.pop("tatlılar", "Silinecek öğe yok!")

Böylelikle sözlükte bulunmayan bir öğeyi silmeye çalıştığımızda Python bize bir hata mesajı göstermek yerine, “Silinecek öğe yok!” şeklinde daha anlamlı bir mesaj verecektir...

6.2.9. popitem metodu

popitem() metodu da bir önceki bölümde öğrendiğimiz pop() metoduna benzer. Bu iki metodun görevleri hemen hemen aynıdır. Ancak pop() metodu parantez içinde bir parametre alırken, popitem() metodunun parantezi boş, yani parametresiz olarak kullanılır. Bu metot bir sözlükten rastgele öğeler silmek için kullanılır. Daha önce de pek çok kez söylediğimiz gibi, sözlükler sırasız veri tipleridir. Dolayısıyla popitem() metodunun öğeleri silerken kullanabileceği bir sıra kavramı yoktur. Bu yüzden bu metot öğeleri rastgele silmeyi tercih eder...

>>> sepet = {"meyveler": ("elma", "armut"), "sebzeler": ("pırasa", "fasulye")}

>>> sepet.popitem()

Bu komut sözlükten rastgele bir anahtarı, değerleriyle birlikte sözlükten silecektir. Eğer sözlük boşsa bu metot bize bir hata mesajı gösterir.

6.2.10. setdefault metodu

Bu metot epey enteresan, ama bir o kadar da yararlı bir mahluktur... Bu metodun ne işe yaradığını doğrudan bir örnek üzerinde görelim:

>>> sepet = {"meyveler": ("elma", "armut"), "sebzeler": ("pırasa", "fasulye")}

>>> sepet.setdefault("içecekler", ("su", "kola"))

Bu komut yardımıyla sözlüğümüz içinde “içecekler” adlı bir anahtar oluşturduk. Bu anahtarın değeri ise (“su”, “kola”) oldu... Bir de şuna bakalım:

>>> sepet.setdefault("meyveler", ("erik", "çilek"))

('elma', 'armut')

Gördüğünüz gibi, sözlükte zaten “meyveler” adlı bir anahtar bulunduğu için, Python aynı adı taşıyan ama değerleri farklı olan yeni bir “meyveler” anahtarı oluşturmadı... Demek ki bu metot yardımıyla bir sözlük içinde arama yapabiliyor, eğer aradığımız anahtar sözlükte yoksa, setdefault() metodu içinde belirttiğimiz özellikleri taşıyan yeni bir anahtar-değer çifti oluşturabiliyoruz.

6.2.11. update metodu

İnceleyeceğimiz son metot update() metodu... Bu metot yardımıyla oluşturduğumuz sözlükleri yeni verilerle güncelleyeceğiz. Diyelim ki elimizde şöyle bir sözlük var:

>>> stok = {"elma": 5, "armut": 10, "peynir": 6, "sosis": 15}

Stoğumuzda 5 adet elma, 10 adet armut, 6 kutu peynir, 15 adet de sosis var. Diyelim ki daha sonraki zamanlarda bu stoğa mal giriş-çıkışı oldu ve stoğun son hali şöyle:

>>> yeni_stok = {"elma": 3, "armut": 20, "peynir": 8, "sosis": 4, "sucuk": 6}

Yapmamız gereken şey, stoğumuzu yeni bilgilere göre güncellemek olacaktır. İşte bu işlemi update() metodu ile yapabiliriz:

>>>updatestok.update(yeni_stok)

>>> print(stok)

{'peynir': 8, 'elma': 3, 'sucuk': 6, 'sosis': 4, 'armut': 20}

Böylelikle malların son miktarlarına göre stok bilgilerimizi güncellemiş olduk...

6.2.12. Sözlük Öğelerini Alfabe Sırasına Dizmek

Daha önce de dediğimiz gibi sözlükler sıralı olmayan veri tipleridir. Dolayısıyla bir sözlüğü ekrana yazdırırken elde edeceğiniz çıktıdaki öğe sıralaması, sözlüğü tanımlarken kullandığınız öğe sıralamasından farklı olacaktır. Mesela:

>>> harfler = {"a": 1, "b": 5, "c": 8, "d": 10, "e": "30"}

>>> harfler

{'a': 1, 'c': 8, 'b': 5, 'e': '30', 'd': 10}

Gördüğünüz gibi, öğelerin sırası çıktıda karışık görünüyor. Peki biz bu sözlüğün öğelerini sıralı olarak çıktı almak istersek ne yapmamız gerekir? Python böyle bir şeyi yapmak için özel bir araç sunmaz. Dolayısıyla bizim bu işlem için başka yollar aramamız gerekecek.

En basit şekilde yukarıdaki sözlüğü şöyle sıralayabiliriz:

>>> for i in sorted(harfler):
...     print(i, harfler[i])
...
a 1
b 5
c 8
d 10
e 30

Burada dikkat ederseniz yeni bir fonksiyonla karşılaştık. Bu yeni fonksiyonun adı sorted(). Bu fonksiyon, işlev olarak listelerin sort() metoduna çok benzer. Ancak sort() metodu yalnızca listeler için geçerlidir. Yani mesela sort() metodunu demetlerle veya sözlüklerle birlikte kullanamayız. Ama sorted() fonksiyonu sıralanabilen bütün veritipleri için kullanılabilir. Bu bakımdan sorted() fonksiyonu sort() metoduna göre çok daha genel bir araçtır ve çok daha kullanışlıdır. Mesela sorted() fonksiyonuyla bir örnek daha yapalım:

>>> demet = ("mehmet", "ahmet", "kezban", "celal")

>>> sorted(demet)

['ahmet', 'celal', 'kezban', 'mehmet']

Gördüğünüz gibi, sorted() fonksiyonu yardımıyla demetin öğelerini alfabe sırasına dizebildik. Bu fonksiyonu listelerle birlikte de kullanabilirsiniz...

Eğer sıralamak istediğiniz demet, liste veya sözlükte Türkçe karakterler varsa, bu metot o demet, liste veya sözlüğü düzgün bir şekilde sıralayamayacaktır. Hatırlarsanız listelerin sort() metodunu incelerken de böyle bir durumla karşılaşmıştık. Orada kullandığımız yöntemi burada da kullanabiliriz:

>>> import locale
>>> locale.setlocale(locale.LC_ALL, "tr_TR.UTF8")

>>> demet = ("mehmet", "ahmet", "kezban", "celal", "çiğdem")

>>> print(sorted(demet, key=locale.strxfrm))

['ahmet', 'celal', 'çiğdem', 'kezban', 'mehmet']

Neyse... Biz konumuza dönelim. Yukarıda sorted() fonksiyonunu kullanarak sözlük öğelerini sıraladık ve şöyle bir çıktı elde ettik:

a 1
b 5
c 8
d 10
e 30

Bu çıktının görüntüsünü hoşunuza gitmediyse, bu çıktıyı biraz biçimlendirmek de elbette mümkündür. Mesela her öğenin arasına, bu öğelerin birbiriyle bağlantılı olduğunu gösterecek bir işaret yerleştirebiliriz:

>>> for i in sorted(harfler):
...     print(i, harfler[i], sep = " --> ")
...
a --> 1
b --> 5
c --> 8
d --> 10
e --> 30

Gördüğünüz gibi, sözlük öğelerini alfabe sırasına dizmek o kadar da zor değil. İsterseniz yukarıdaki döngüyü nasıl kurduğumuzu biraz inceleyelim:

İlk satırda bildiğimiz şekilde bir for döngüsü oluşturuyoruz. Burada bir yenilik olarak sorted() fonksiyonunu öğrendik. Bu fonksiyon bize öğeleri sıralama imkanı tanıyor:

>>> for i in sorted(harfler):
...

İkinci satırda gördüğümüz kodlar biraz kafanızı karıştırmış olabilir. Belki ilk bakışta bu satırın ne işe yaradığını anlamak çok kolay olmayabilir. Ama aslında hem çok kolay, hem de çok mantıklı bir koddur bu. İsterseniz kodlarımızı şu şekilde sadeleştirerek olayların arka yüzünü görmeye çalışabiliriz:

>>> for i in sorted(harfler):
...     print(i)
...
a
b
c
d
e

Burada “sorted(sözlük)” ifadesinin nasıl bir çıktı verdiğine baktık. Gördüğünüz gibi, bu ifade, sözlüğün anahtarlarını alfabe sırasına diziyor. Ama sözlükteki değerlerle ilgili herhangi bir işlem yapmıyor. Yani bu ifade, “anahtar-değer” çiftlerinden oluşan sözlüğümüz içinde sadece “anahtar” kısmıyla ilgileniyor, değer kısmını es geçiyor. Bizim bir yolunu bulup, sorted() ile elde ettiğimiz sıralı anahtarları, bunlara karşılık gelen değerlerle eşleştirmemiz gerekiyor. Hatırlarsanız bir sözlüğün öğelerine şu şekilde ulaşıyorduk:

>>> harfler[anahtar]

Bunu kendi sözlüğümüze uyarlayalım:

>>> harfler["a"]

1

>>> harfler["b"]

5

İşte yukarıdaki örnekte de sözlüklerin bu özelliğinden faydalandık. Şu satırı tekrar gözümüzün önüne getirelim:

>>> print(i, harfler[i])

Burada dikkat ederseniz, for döngüsü içinde “i” adını vererek aldığımız bütün sözlük anahtarlarını tek tek sözlük[anahtar] şeklinde uyguluyoruz. Kodlarımıza tekrar bütün olarak bakalım:

>>> for i in sorted(harfler):
...     print(i, harfler[i], sep = " --> ")

Burada önce sözlükteki anahtarları alfabe sırasına dizip her birine “i” adını veriyoruz. Daha sonra print() fonksiyonu içinde öncelikle bu “i”leri ekrana basıyoruz. Bu “i”lerle birlikte ayrıca “sözlük[i]” kodunu kullanarak, “i” adını verdiğimiz her bir anahtarın değerini de çağırıyoruz. Satırın en sonundaki “sep” parçacığının görevini biliyorsunuz zaten. Bu parçacık burada bize “estetik” bir fayda sunuyor... Ve nihayet şu çıktıyı elde ediyoruz:

a --> 1
b --> 5
c --> 8
d --> 10
e --> 30

6.2.13. Sözlükten Öğe Silmek

Sözlüklerin metotlarını işlerken pop() ve popitem() adlı metotları görmüştük. Bu metotlar yardımıyla sözlükteki öğeleri silebiliyorduk. Yalnız bu metotlar silinen öğeleri de otomatik olarak ekrana basıyorlardı. Bizim ihtiyacımız olan şey listelerdeki remove() metodu gibi bir şey olabilir. Yani silinen öğeyi dünya aleme duyurmadan silmek istiyor olabiliriz, değil mi?

Eğer böyle bir isteğimiz varsa bunu daha önce bir kez gördüğümüz del deyimi yardımıyla yapabiliriz. Hatırlarsanız del deyimini bütün bir listeyi ortadan kaldırmak için kullanmıştık. İstersek bu del deyimini sözlükteki tek bir öğeyi silmek için de kullanabiliriz:

>>> stok = {'peynir': 8, 'elma': 3, 'sucuk': 6, 'sosis': 4, 'armut': 20}

>>> del stok["peynir"]

Bu şekilde stoktaki “peynir” anahtarını değeriyle birlikte silmiş olduk...

Daha önceki konulardan hatırladığımız bir de clear() metodu var. Bu metot ise bütün bir listeyi boşaltmak için kullanılıyor. clear() metodunun görevi elimize boş bir liste vermektir.