Python'da sözlükler (dict): oluşturma, metotlar, dolaşma, sıralama ve frozendict
Python'da sözlük (dict), anahtar-değer çiftlerinden oluşan değiştirilebilir bir koleksiyondur ve değeri anahtarla neredeyse anında bulur; {"kahve": 250} biçiminde süslü parantezlerle ya da dict() fonksiyonuyla oluşturulur. Anahtarlar benzersiz ve özetlenebilir olmalıdır, Python 3.7'den beri ekleme sırası korunur, Python 3.15'te ise yerleşik değiştirilemez bir tür olan frozendict gelmiştir.
Python'da sözlük (dict), anahtar-değer çiftlerinden oluşan bir koleksiyondur; kaç kayıt olursa olsun, değer anahtarla neredeyse anında bulunur. Harcamaları kategorilere göre saymak, ayarları tutmak ya da bir kullanıcıyı kimliğiyle hızlıca aramak istediğinizde sözlük kullanırsınız. Aşağıda python dict ile çalışmanın her yönü var: oluşturma, metotlar, dolaşma, sıralama, birleştirme ve 3.15'in yeni tipi frozendict.
Python'da sözlük nedir
Sözlük çiftleri saklar ve anahtar benzersizdir: var olan bir anahtara değer yazarsanız eski değer üzerine yazılır. İç yapısı bir hash tablosudur; bu yüzden anahtara göre arama, ekleme ve silme işlemleri ortalama olarak sabit sürede çalışır, tüm kayıtlar taranmaz.
Anahtar olarak yalnızca özetlenebilir (hashable) bir nesne kullanılabilir: metin, sayı, değiştirilemeyen değerlerden oluşan demet. Liste anahtar olamaz; TypeError: unhashable type: 'list' hatası alırsınız. Değerler ise her şey olabilir, başka sözlükler ve listeler dahil.
Python 3.7'den itibaren sözlük ekleme sırasını garanti eder: dolaşırken anahtarlar eklendikleri sırayla gelir.
Sözlük nasıl oluşturulur
Sözlük oluşturmanın birkaç yolu vardır ve hepsi gerçek kodda karşınıza çıkar.
spent = {"Yiyecek": 1200, "Taksi": 450} # değişmez değer (literal)
empty = {} # boş sözlük
also_empty = dict() # dict fonksiyonuyla aynısı
user = dict(name="Ayşe", age=30) # adlandırılmış argümanlarla
pairs = dict([("a", 1), ("b", 2)]) # çiftlerden oluşan listeyle
keys = dict.fromkeys(["x", "y"], 0) # {'x': 0, 'y': 0}
Dikkat: boş süslü parantez {} boş bir kümeyi değil, boş bir sözlüğü oluşturur. Boş küme yalnızca set() ile yapılır.
İki listeden sözlük kurmanın kullanışlı yolu zip'tir:
names = ["Yiyecek", "Taksi", "Sinema"]
sums = [1200, 450, 600]
spent = dict(zip(names, sums))
print(spent) # {'Yiyecek': 1200, 'Taksi': 450, 'Sinema': 600}
Anahtarla erişim: d[k] ve get
Değer köşeli parantezle okunur. Anahtar yoksa Python KeyError fırlatır. Hata almamak için get metodunu kullanın: anahtar yoksa None ya da verdiğiniz varsayılan değeri döndürür.
spent = {"Yiyecek": 1200}
print(spent["Yiyecek"]) # 1200
print(spent.get("Sinema")) # None
print(spent.get("Sinema", 0)) # 0
spent["Sinema"] # KeyError: 'Sinema'
Bir anahtarın var olup olmadığını in operatörüyle sorarsınız: "Yiyecek" in spent değeri True'dur. Operatör yalnızca anahtarlara bakar, değerlere bakmaz. Değerler için 1200 in spent.values() yazın.
Ekleme, değiştirme ve silme
Kayıt eklemek ya da güncellemek tek satırlık bir atamadır. Sayım yaparken get ile birlikte kullanmak çok pratiktir:
spent = {}
for category, amount in [("Yiyecek", 250), ("Taksi", 300), ("Yiyecek", 400)]:
spent[category] = spent.get(category, 0) + amount
print(spent) # {'Yiyecek': 650, 'Taksi': 300}
Bir anahtarı del d[k] ile silebilirsiniz (anahtar yoksa KeyError verir) ya da değeri de döndüren d.pop(k, varsayılan) ile. Sözlüğün tamamını temizlemek için d.clear(). Kayıt sayısı, yani çift sayısı, len(d) ile alınır.
Sözlük metotları: kısa liste
| Metot | Ne yapar |
|---|---|
get(k, varsayılan) | anahtarın değerini ya da varsayılanı hata vermeden döndürür |
setdefault(k, varsayılan) | değeri döndürür; anahtar yoksa önce varsayılanı yazar |
update(diğer) | diğer sözlükteki çiftleri ekler ve üzerine yazar |
pop(k, varsayılan) | anahtarı siler ve değerini döndürür |
popitem() | en son eklenen çifti siler ve döndürür |
keys(), values(), items() | anahtarların, değerlerin ve çiftlerin görünümleri |
copy() | yüzeysel kopya |
clear() | sözlüğü temizler |
fromkeys(anahtarlar, değer) | aynı değerli yeni bir sözlük |
setdefault: değerleri listelerle doldurmak
Değerler liste olduğunda ve veriyi gruplamanız gerektiğinde setdefault işinizi görür:
groups = {}
for item, cat in [("kahve", "Yiyecek"), ("metro", "Ulaşım"), ("pizza", "Yiyecek")]:
groups.setdefault(cat, []).append(item)
print(groups) # {'Yiyecek': ['kahve', 'pizza'], 'Ulaşım': ['metro']}
update: sözlüğü güncellemek
update sözlüğü yerinde değiştirir: yeni anahtarlar eklenir, aynı olanların değerleri yeniden yazılır.
cfg = {"debug": False, "lang": "tr"}
cfg.update({"debug": True, "theme": "dark"})
print(cfg) # {'debug': True, 'lang': 'tr', 'theme': 'dark'}
defaultdict: varsayılan değeri olan sözlük
collections.defaultdict, dict'in bir alt sınıfıdır: var olmayan bir anahtara erişildiğinde değeri kendi verdiğiniz fabrika fonksiyonuyla kendisi oluşturur. Sayım ve gruplama kodu böylece kısalır.
from collections import defaultdict
spent = defaultdict(int)
for cat, amount in [("Yiyecek", 250), ("Taksi", 300), ("Yiyecek", 400)]:
spent[cat] += amount
print(dict(spent)) # {'Yiyecek': 650, 'Taksi': 300}
groups = defaultdict(list)
groups["Yiyecek"].append("kahve")
Yalnızca sayım yapacaksanız collections.Counter da var: Counter(["a", "b", "a"]) sonucu Counter({'a': 2, 'b': 1}) olur.
Sözlükte dolaşmak: for döngüsü
Bir sözlük for döngüsünde varsayılan olarak anahtarları verir. Anahtar ve değeri birlikte almak için en sık kullanılan yol items()'tır.
spent = {"Yiyecek": 650, "Taksi": 300}
for cat in spent: # anahtarlar
print(cat)
for amount in spent.values(): # değerler
print(amount)
for cat, amount in spent.items(): # çiftler
print(f"{cat}: {amount} TL")
Dolaşırken sözlüğün boyutunu değiştiremezsiniz; RuntimeError: dictionary changed size during iteration hatası alırsınız. Bir kısım anahtarı silmeniz gerekiyorsa kopya üzerinde dolaşın: for k in list(d):.
Sözlüğü ekrana yazdırmak
print(d) sözlüğü tek satırda yazdırır. Büyük ya da iç içe sözlükler için pprint modülü ya da json.dumps(d, ensure_ascii=False, indent=2) daha uygundur: veriyi girintili ve Türkçe karakterleri kaçırmadan gösterir.
Sözlük sıralama
Sözlük kendi içinde sıralanmaz; sort metodu yoktur. Sözlüğü sıralamak, sorted ile sıralanmış çiftlerden yeni bir sözlük kurmak demektir.
spent = {"Taksi": 300, "Yiyecek": 650, "Sinema": 120}
by_key = dict(sorted(spent.items()))
print(by_key) # {'Sinema': 120, 'Taksi': 300, 'Yiyecek': 650}
by_value = dict(sorted(spent.items(), key=lambda p: p[1], reverse=True))
print(by_value) # {'Yiyecek': 650, 'Taksi': 300, 'Sinema': 120}
Yalnızca ilk N kategoriye ihtiyacınız varsa sonucu tekrar sözlüğe çevirmeyin: sorted(spent.items(), key=lambda p: p[1], reverse=True)[:2] çiftlerden oluşan bir liste döndürür.
Sözlüklerden oluşan bir listeyi bir alana göre sıralamak için: sorted(users, key=lambda u: u["age"]).
Sözlükleri birleştirmek
Python 3.9'dan itibaren sözlükler | operatörüyle birleşir; |= ise sözlüğü yerinde günceller. Anahtarlar çakışırsa sağdaki operand kazanır.
a = {"x": 1, "y": 2}
b = {"y": 20, "z": 3}
print(a | b) # {'x': 1, 'y': 20, 'z': 3}
print({**a, **b}) # aynısı açma (unpacking) ile
a |= b # a.update(b) ile aynı
Dikkat: sözlüklerde a + b çalışmaz, TypeError verir. Aynı anahtarların değerlerini toplamak istiyorsanız Counter kullanın: Counter(a) + Counter(b).
Sözlük açma
Çift yıldız ** bir sözlüğü fonksiyonun adlandırılmış argümanlarına ya da başka bir sözlüğe açar:
def greet(name, city):
return f"{name}, {city}'dan"
data = {"name": "Ayşe", "city": "Ankara"}
print(greet(**data)) # Ayşe, Ankara'dan
Sözlük üretimi (dict comprehension)
Sözlük üretimi, herhangi bir diziden tek satırda sözlük kurar:
squares = {n: n * n for n in range(5)}
print(squares) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
big = {k: v for k, v in spent.items() if v > 200}
inverted = {v: k for k, v in {"a": 1, "b": 2}.items()}
print(inverted) # {1: 'a', 2: 'b'}
Son örnek sözlüğü ters çevirir: anahtarlar ve değerler yer değiştirir. Bu yöntem yalnızca değerler benzersiz ve özetlenebilir olduğunda çalışır; aksi halde bazı çiftler kaybolur.
İç içe sözlükler
Bir değer başka bir sözlük olabilir. JSON yanıtlarını ya da kullanıcıların sözlüğünü tutan yapılar böyle kurulur.
users = {
101: {"name": "Ayşe", "skills": ["python", "sql"]},
102: {"name": "Ali", "skills": ["go"]},
}
print(users[101]["skills"][0]) # python
print(users.get(103, {}).get("name")) # None, KeyError olmadan
Sözlük kopyalamak: kopya mı, ikinci isim mi
b = a satırı sözlüğü kopyalamaz; aynı nesneye ikinci bir ad verir. b üzerinden yapılan değişiklikler a'da da görünür. Sözlüğü bir fonksiyona vermek de aynı şekilde çalışır: fonksiyon ortak nesneyi alır ve farkında olmadan bozabilir.
import copy
a = {"limits": [0, 500]}
b = a.copy() # yüzeysel kopya
b["limits"].append(1000) # iç liste ortak!
print(a) # {'limits': [0, 500, 1000]}
c = copy.deepcopy(a) # tamamen bağımsız kopya
Sözlükleri karşılaştırmak
== operatörü sözlükleri içeriğine göre karşılaştırır: tüm çiftler aynıysa eşittirler. Anahtarların sırası dikkate alınmaz: {"a": 1, "b": 2} == {"b": 2, "a": 1} ifadesi True verir. Ortak anahtarları bulmak için görünümler üzerinde küme işlemleri kullanın: a.keys() & b.keys().
Tipli sözlük: tür ipuçları
Sözlüğün tür ipucu dict[str, int] biçiminde yazılır. Alanları sabit ve türleri farklı olan bir sözlük için typing modülündeki TypedDict uygundur:
from typing import TypedDict
class User(TypedDict):
name: str
age: int
u: User = {"name": "Ayşe", "age": 30}
Tür ipuçları çalışma zamanında denetlenmez; bunları IDE'ler ve mypy gibi analiz araçları okur.
Değiştirilemeyen sözlük: Python 3.15'te frozendict
Python 3.15 ile yerleşik frozendict tipi geldi (PEP 814): içe aktarmaya gerek yoktur ve değiştirmeye çalışmak doğrudan TypeError ile sonuçlanır. Daha önce değiştirilemeyen sözlük, types modülündeki bir sarmalayıcıyla ya da üçüncü taraf bir paketle taklit edilirdi. Bu, hiçbir fonksiyonun sessizce değiştiremeyeceği ortak ayarlar için tam aradığınız şeydir.
config = frozendict(min_amount=0, max_amount=500)
config["max_amount"] = 1000
# TypeError: 'frozendict' object does not support item assignment
strict = config | {"max_amount": 300} # yeni bir frozendict, orijinal duruyor
cache = {config: "mayıs raporu"} # özetlenebilir — anahtar olabilir
Kurs materyallerine göre bilmeniz gerekenler:
frozendict,dict'ten değilobject'ten türer; bu yüzdenisinstance(cfg, dict)Falsedöndürür. "Herhangi bir sözlük" kontrolü içincollections.abc.Mappingya daisinstance(x, (dict, frozendict))kullanın.- Özetlenebilir yalnızca anahtarları ve değerleri özetlenebilirse:
frozendict(a=[1])oluşturulur, amahash()çağrısı hata verir. Değiştirilemezlik sığdır, tıpkı demetlerde olduğu gibi. - Sıra korunur, ama
==karşılaştırması sırayı dikkate almaz. json.dumps,picklevecopyfrozendict'i tanır.
Tipik hatalar
- Okurken KeyError —
getya dainile kontrol edin. - Anahtar olarak liste — listeyi demete çevirin:
d[tuple(lst)]. - Döngü sırasında değiştirmek —
list(d)üzerinde dolaşın. - Atamanın kopya yaptığını sanmak —
copy()ya dadeepcopykullanın. - Boş küme yerine
{}— bu boş bir sözlüktür.
Özet
Python dict, dilin temel veri yapısıdır: anahtarla hızlı arama, ekleme sırasının korunması, get, setdefault, update gibi kullanışlı metotlar, items() ile dolaşma, sorted ile sıralama ve | ile birleştirme. Kopyalamayı ve özetlenebilir anahtarları akılda tutun; Python 3.15'te değiştirilemeyen ayarlar için frozendict kullanın. Sözlükler, listeler, demetler ve kümeler "Python 3.15: sıfırdan uzmanlığa" kursunda harcama takipçisi örneğiyle uygulamalı olarak işlenir.
Sık sorulan sorular
Bir sözlükte farklı türde değerler tutabilir miyim?
Evet, değerler aynı sözlükte bile farklı türde olabilir: sayılar, metinler, listeler, başka sözlükler. Kısıtlama yalnızca anahtarlar için geçerlidir; özetlenebilir olmak zorundadırlar.
Bir sözlükte kaç eleman olduğunu nasıl öğrenirim?
len(d) çift sayısını verir. Boş bir sözlük için 0 döner ve boş sözlük if koşulunda yanlış sayılır.
dict ile defaultdict arasındaki fark nedir?
defaultdict, dict'in bir alt sınıfıdır; var olmayan bir anahtara erişildiğinde KeyError vermek yerine int ya da list gibi bir fabrikayla değer üretir. Diğer davranışları aynıdır.
Değere göre anahtarı nasıl bulurum?
Doğrudan bir metot yoktur; döngü gerekir: next((k for k, v in d.items() if v == value), None). Bu sık yapılıyorsa ters bir sözlük kurun: {v: k for k, v in d.items()}.
Bir sözlüğü dosyaya nasıl kaydederim?
Genellikle json modülüyle: yazma modunda açılmış dosyaya json.dump(d, f, ensure_ascii=False, indent=2), okumak için json.load(f). Anahtarlar bu durumda metne dönüşür.
Bu konu “Python 3.15: от новичка до профи” kursunda uygulamalı olarak ayrıntılı işleniyor.
Kursa git