🐍 8.5: Python'da Hash Table

dict - En Çok Kullanılan Veri Yapısı!

🎯 Python dict Nedir?

Python'un yerleşik dictionary (dict) veri yapısı, hash table implementasyonudur!

✨ Neden Bu Kadar Önemli?

  • Python'un en hızlı veri yapısı (O(1) erişim)
  • JSON, API, veritabanı - her yerde kullanılır
  • Modül import sistemi bile dict kullanır
  • Class'ların attribute'ları dict olarak saklanır
dict Temel Kullanım
# dict oluşturma yöntemleri
print("=== dict Oluşturma ===")

# 1. Süslü parantez
ogrenci = {
    "ad": "Ahmet",
    "soyad": "Yılmaz",
    "yas": 20,
    "not": 85
}
print(f"1. Yöntem: {ogrenci}")

# 2. dict() fonksiyonu
ogrenci2 = dict(ad="Mehmet", soyad="Kaya", yas=22)
print(f"2. Yöntem: {ogrenci2}")

# 3. Listeden
veriler = [("ad", "Ayşe"), ("yas", 19)]
ogrenci3 = dict(veriler)
print(f"3. Yöntem: {ogrenci3}")

print("\n=== Erişim ===")
# Erişim - O(1)
print(f"Öğrencinin adı: {ogrenci['ad']}")
print(f"Öğrencinin notu: {ogrenci['not']}")

# Güvenli erişim (yoksa None döner)
print(f"Şube: {ogrenci.get('sube', 'Belirtilmemiş')}")

print("\n=== Ekleme/Güncelleme ===")
# Ekleme/Güncelleme - O(1)
ogrenci["sube"] = "A"
print(f"Şube eklendi: {ogrenci}")

ogrenci["not"] = 90  # Güncelleme
print(f"Not güncellendi: {ogrenci}")

print("\n=== Silme ===")
# Silme - O(1)
del ogrenci["sube"]
print(f"Şube silindi: {ogrenci}")

# pop ile silme (değer döndürür)
yas = ogrenci.pop("yas")
print(f"Yaş silindi (değer: {yas}): {ogrenci}")

print("\n=== Kontroller ===")
# Anahtar var mı? - O(1)
print(f"'ad' var mı? {'ad' in ogrenci}")
print(f"'yas' var mı? {'yas' in ogrenci}")

# Boyut
print(f"Eleman sayısı: {len(ogrenci)}")
Çıktı bekleniyor...

🔄 dict Döngüleri

dict Üzerinde Döngü
notlar = {
    "Ali": 85,
    "Veli": 92,
    "Ayşe": 78,
    "Fatma": 95
}

print("=== Sadece Anahtarlar ===")
for isim in notlar:
    print(isim)

print("\n=== Sadece Değerler ===")
for not_degeri in notlar.values():
    print(not_degeri)

print("\n=== Anahtar-Değer Çiftleri ===")
for isim, not_degeri in notlar.items():
    print(f"{isim}: {not_degeri}")

print("\n=== Şartlı Filtre (comprehension) ===")
# 90'dan yüksek notlar
yuksek_notlar = {isim: not_degeri 
                 for isim, not_degeri in notlar.items() 
                 if not_degeri >= 90}
print(f"90+ notlar: {yuksek_notlar}")

# Not ortalaması
ortalama = sum(notlar.values()) / len(notlar)
print(f"\nOrtalama: {ortalama:.1f}")
Çıktı bekleniyor...

⚡ dict Performansı

⏱️ Zaman Karmaşıklığı

İşlem Ortalama En Kötü
d[key] (erişim) O(1) O(n)
d[key] = val (ekleme) O(1) O(n)
del d[key] O(1) O(n)
key in d O(1) O(n)
len(d) O(1) O(1)

*En kötü durum: Çok kötü hash fonksiyonu veya tüm çakışmalar

dict vs list Hız Karşılaştırması
import time

# 10,000 elemanlı veri
n = 10000
liste = list(range(n))
sozluk = {i: i for i in range(n)}

print(f"=== {n} Elemanda Arama Hızı ===\n")

# Liste'de arama (O(n))
aranan = 9999
start = time.time()
for _ in range(1000):
    result = aranan in liste
end = time.time()
list_time = (end - start) * 1000
print(f"Liste (O(n)): {list_time:.2f} ms")

# dict'te arama (O(1))
start = time.time()
for _ in range(1000):
    result = aranan in sozluk
end = time.time()
dict_time = (end - start) * 1000
print(f"dict (O(1)): {dict_time:.2f} ms")

speedup = list_time / dict_time
print(f"\n⚡ dict {speedup:.0f}x daha hızlı!")

# Bellek kullanımı
import sys
print(f"\n=== Bellek Kullanımı ===")
print(f"Liste: {sys.getsizeof(liste):,} byte")
print(f"dict: {sys.getsizeof(sozluk):,} byte")
print(f"dict ~{sys.getsizeof(sozluk) / sys.getsizeof(liste):.1f}x daha fazla bellek")
Çıktı bekleniyor...

💡 dict İpuçları ve Yaygın Hatalar

❌ Yaygın Hatalar

  1. Liste anahtarı kullanmak: Liste hash'lenemez!
    # ❌ YANLIŞ
    d = {[1, 2]: "değer"}  # TypeError!
    
    # ✅ DOĞRU (tuple kullan)
    d = {(1, 2): "değer"}
  2. Döngü sırasında değiştirmek:
    # ❌ YANLIŞ
    for key in d:
        del d[key]  # RuntimeError!
    
    # ✅ DOĞRU
    for key in list(d.keys()):
        del d[key]

✅ İyi Pratikler

  • Yoksa default değer: d.get(key, default)
  • Yoksa ekle: d.setdefault(key, [])
  • Birleştir: d1.update(d2) veya {**d1, **d2}
  • Tersine çevir: {v: k for k, v in d.items()}

📋 Özet

✅ Bu Bölümde Öğrendikleriniz

  • dict: Python'un hash table implementasyonu
  • O(1): Erişim, ekleme, silme çok hızlı
  • Anahtar: Sadece hashable tipler (int, str, tuple)
  • Döngü: keys(), values(), items()
  • Performans: Liste'den çok daha hızlı arama