Python'da JSON verisini okumak için dosyadan json.load, metinden json.loads kullanırsın; veri Python nesnesine dönüşür. İç içe bir JSON yapısını okurken her sözlük seviyesine anahtarla, her liste seviyesine indeksle inersin. Yani yol, verinin kendi şeklini soldan sağa izleyen küçük adımlardan oluşur.
Önce veri türünü bul, sonra doğru erişim işaretini seç
İç içe veride en sık yapılan hata, türü bilmeden elemana uzanmaktır. Karar sırası basittir: bulunduğun noktadaki değerin türüne bak, sonra ona uyan erişim işaretini seç.
JSON'daki nesne Python'da sözlüğe (dict), dizi ise listeye (list) dönüşür. Dönüştürme işi şu kadar kısadır:
import json
with open("veri.json", encoding="utf-8") as dosya:
veri = json.load(dosya) # dosyadan okur
veri = json.loads(metin) # elindeki JSON metninden okur
Aradaki fark kaynaktadır: load açık bir dosya nesnesi ister, loads metin (str) ister. İkisinin sonunda da elinde normal bir Python nesnesi olur. Bu yazıdaki örneklerde metinle çalışacağız; dosyadan okuduğunda sonraki adımlar aynıdır.
Şimdi asıl kural: Sözlükte anahtar, listede indeks kullanılır; iç içe yapı için bu iki erişim biçimi sırayla birleştirilir. Aşağıdaki tablo bu kararı özetler.
| Veri türü | Erişim işareti | Örnek |
|---|---|---|
Sözlük (dict) | Anahtar ve köşeli parantez | veri["kitaplar"] |
Liste (list) | İndeks (0'dan başlar) | kitaplar[0] |
Metin (str) ya da sayı (int, float) | Erişim yok, değer olduğu gibi kullanılır | baslik |
Türden emin değilsen her adımda type() ile kontrol et:
print(type(veri))
print(type(veri["kitaplar"]))
Çıktı, örneğin şöyle olur:
<class 'dict'>
<class 'list'>
İlk satır en dıştaki değerin sözlük olduğunu, ikinci satır "kitaplar" anahtarının altında liste durduğunu söyler. Bir sonraki adımda ne yazacağını bu iki çıktı belirler. Sözlük ve liste erişimini hızlıca ölçmek istersen ücretsiz Python bilgi testi temel veri yapılarındaki seviyeni görmene yardımcı olabilir.
Kitaplar ve yazarlar örneğiyle sözlük içinde liste, liste içinde sözlük

Örnekte en üst seviye bir sözlük var. İçindeki "kitaplar" anahtarı bir liste tutuyor, listenin her elemanı da bir sözlük. Yazar bilgisi ise kitabın içinde ayrı bir sözlük olarak duruyor.
import json
metin = """{
"kitaplar": [
{"baslik": "Sefiller", "yazar": {"ad": "Victor Hugo"}},
{"baslik": "Kürk Mantolu Madonna", "yazar": {"ad": "Sabahattin Ali"}}
]
}"""
veri = json.loads(metin)
kitaplar = veri["kitaplar"]
print(kitaplar[0]["baslik"])
print(kitaplar[1]["yazar"]["ad"])
for kitap in kitaplar:
print(kitap["baslik"])
Beklenen çıktı:
Sefiller
Sabahattin Ali
Sefiller
Kürk Mantolu Madonna
Her ifadeyi soldan sağa okuyalım:
veri["kitaplar"]:verisözlüğünde"kitaplar"anahtarına git; karşında bir liste var.kitaplar[0]["baslik"]: listenin ilk elemanını al (bu bir sözlük), sonra o sözlükte"baslik"anahtarının değerini oku. Sonuç düz bir metindir.kitaplar[1]["yazar"]["ad"]: ikinci kitaba geç,"yazar"anahtarıyla iç sözlüğe in, orada"ad"değerini al.for kitap in kitaplar: listede indeks yazmadan tek tek dolaşır; her turdakitapbir sözlüktür, bu yüzden içinden anahtarla değer alırsın.
Dikkat edersen köşeli parantezlerin içine ne yazacağını, o noktadaki değerin türü belirliyor: sözlükte metin anahtar, listede tam sayı indeks. Yol uzadıkça ifade uzar ama mantık değişmez.
Çok seviyeli yapıyı adım adım nasıl çözersin?

veri["kitaplar"][1]["yazar"]["ad"] gibi uzun bir ifadeyi tek seferde yazmak yerine her seferinde bir seviye in, ulaştığın değeri bir değişkene ata ve type() ile türüne bak. Tür sözlükse sıradaki işaret anahtardır, listeyse indekstir. Yol netleşince ara değişkenleri silip ifadeyi tek satıra birleştirirsin.
- En üst nesnenin türünü bul.
- Türe göre anahtarı ya da indeksi seç.
- Sonucu bir değişkene ata.
- Yeni değerin türüne bakıp bu adımları tekrarla.
veri = {
"kitaplar": [
{"baslik": "Sefiller", "yazar": {"ad": "Victor Hugo", "ulke": "Fransa"}},
{"baslik": "Suç ve Ceza", "yazar": {"ad": "Dostoyevski", "ulke": "Rusya"}}
]
}
kitaplar = veri["kitaplar"]
print(type(kitaplar))
kitap = kitaplar[1]
print(type(kitap))
yazar = kitap["yazar"]
print(type(yazar))
ad = yazar["ad"]
print(ad)
print(veri["kitaplar"][1]["yazar"]["ad"])
Beklenen çıktı:
<class 'list'>
<class 'dict'>
<class 'dict'>
Dostoyevski
Dostoyevski
Son iki satır aynı değeri verir. Tek satırlık ifade, aşağıdaki dört adımın birleştirilmiş hâlidir. Bir yerde hata alırsan ara değişkenleri geri açıp print() ile her seviyeyi yazdırabilirsin; hatanın hangi adımda çıktığı hemen görünür.
Sözlük ve liste mantığını temelden pekiştirmek istersen ücretsiz Sıfırdan Temel Python video eğitimini kendi hızında izleyebilirsin.
Eksik anahtar ve liste sınırı: get ve uzunluk kontrolü
Gerçek JSON verilerinde her kayıt aynı alanlara sahip olmayabilir. Köşeli parantezle okuduğunda olmayan anahtar programı durdurur. get() ise anahtar yoksa hata vermez, None döndürür. İstersen ikinci parametreyle varsayılan bir değer de verebilirsin.
kitaplar = [
{"baslik": "Sefiller", "yazar": {"ad": "Victor Hugo"}},
{"baslik": "Suç ve Ceza"}
]
if kitaplar:
kitap = kitaplar[1]
print(kitap.get("baslik"))
print(kitap.get("sayfa"))
print(kitap.get("sayfa", "Bilinmiyor"))
yazar = kitap.get("yazar")
if yazar is not None:
print(yazar.get("ad"))
else:
print("Yazar bilgisi yok")
print(len(kitaplar))
Beklenen çıktı:
Suç ve Ceza
None
Bilinmiyor
Yazar bilgisi yok
2
Zincirleme get kullanırken dikkat
kitap.get("yazar").get("ad") yazarsan ve "yazar" anahtarı yoksa ilk get() None döndürür. İkinci get() ise None üzerinde çağrıldığı için AttributeError verir. Yukarıdaki örnekteki gibi ara değeri değişkene alıp kontrol etmek en okunaklı çözümdür. Kısa bir alternatif, ara adımda boş sözlük vermektir: kitap.get("yazar", {}).get("ad", "Bilinmiyor"). Ancak JSON'da alan açıkça null olarak yazılmışsa Python'da anahtar vardır ve değeri None'dır. Bu durumda varsayılan değer devreye girmez, o yüzden is not None kontrolü daha güvenlidir.
Listede indekse bakmadan önce
Liste için get() yoktur. Boş bir listede kitaplar[0] yazmak IndexError üretir. İndeks kullanmadan önce if kitaplar: ile listenin boş olmadığını, belirli bir sıraya gideceksen len(kitaplar) > 1 gibi bir koşulla o sıranın var olduğunu doğrula. Öğrenci Portalı'ndaki soru bankalarında bu tür hata senaryolarını küçük sorularla tekrar edebilirsin.
KeyError, IndexError ve TypeError neden olur, nasıl düzeltilir?
Bu üç hata da aynı kökten gelir: yapının hangi seviyesinde olduğunu yanlış sanmak. Aşağıdaki örneklerde veri şu şekilde:
veri = {"kitaplar": [{"baslik": "Sefiller"}]}
KeyError: anahtar yok
print(veri["kitap"]) # KeyError: 'kitap'
print(veri["kitaplar"]) # doğrusu
Mesaj, aranan anahtarı gösterir. Yazım, büyük küçük harf ya da yanlış seviyede arama bu hatanın tipik nedenleridir. Sözlükte veri[0] yazarsan da KeyError: 0 alırsın, çünkü 0 bir anahtar olarak aranır.
IndexError: liste sınırı aşıldı
print(veri["kitaplar"][3]) # IndexError: list index out of range
if len(veri["kitaplar"]) > 3:
print(veri["kitaplar"][3])
Tek elemanlı listede geçerli indeks yalnızca 0'dır. Boş listede hiçbir indeks geçerli değildir.
TypeError: yanlış erişim işareti
print(veri["kitaplar"]["baslik"]) # TypeError: list indices must be integers or slices, not str
print(veri["kitaplar"][0]["baslik"]) # Sefiller
Mesaj, listeye metinle erişmeye çalıştığını söyler. Önce [0] ile bir eleman seç, sonra anahtarı kullan.
Teşhis kontrol listesi
- Hata mesajını sonuna kadar oku: hata türü ve hatalı değer orada yazar.
print(type(deger))ile o noktadaki verinin liste mi sözlük mü olduğunu yazdır.- Köşeli parantezleri soldan sağa say; her seviyenin işaretini yapıyla karşılaştır.
- Düzelttikten sonra kodu baştan çalıştır ve çıktıyı kontrol et.
Öğrenci Portalı'ndaki soru bankalarında sözlük ve liste soruları çözerek bu erişim kalıplarını konu konu pekiştirebilirsin.
Bu yapıyı kendi projelerinde birlikte ilerleyerek öğrenmek istersen birebir Python özel ders programına göz atabilirsin.
İç içe veride yolunu bulmak, her adımda elindeki verinin türüne bakmaktan geçer.