Python "TypeError: list indices must be integers or slices, not str" hatasını çözmek için önce erişmeye çalıştığın verinin liste mi, sözlük mü olduğunu belirlemelisin. Liste elemanlarına tam sayı indeksi veya dilimle erişilir, metin anahtarıyla erişim ise sözlük yapısına aittir.
Bu nedenle bir liste üzerinde ['name'] kullanmak yerine, listenin konumunu belirten [0] gibi bir indeks ya da [1:3] gibi bir dilim kullanılmalıdır. Veride metin anahtarları varsa dış yapı büyük olasılıkla sözlük veya sözlük içeren iç içe bir yapıdır.
Hata mesajını parçalayarak sorunun kaynağını bul
Hata mesajındaki list, Python’ın işlem sırasında karşılaştığı değerin bir liste olduğunu belirtir. Değişkenin adının list olması gerekmez. integers ifadesi, 0, 1 ve 2 gibi tam sayı indekslerini anlatır. Liste elemanlarına bu konum numaralarıyla erişilir.
slices ifadesi, listenin belirli bir bölümünü seçen dilimleri ifade eder. [başlangıç:bitiş:adım] biçiminde yazılır. Başlangıç konumu kapsanır, bitiş konumu kapsanmaz. str ise “string” kelimesinin kısaltmasıdır ve "name" gibi metin değerlerini belirtir.
Bir listeye students['name'] yazıldığında Python, 'name' metnini liste içinde bir konum olarak kullanmaya çalışır. Ancak listeler metin anahtarlarıyla değil, tam sayı indeksleriyle çalışır. Aşağıdaki örnekte hem tek bir elemana hem de bir dilime erişilebilir:
students = ["Ada", "Mert", "Zeynep", "Elif"]
print(students[0])
print(students[1:3])
students[0] listenin ilk elemanını, students[1:3] ise birinci ve ikinci indekslerdeki elemanları getirir. Beklenen çıktı şöyledir:
Ada
['Mert', 'Zeynep']
Buradaki temel ayrım şudur: [0] tek bir konuma, [1:3] bir aralığa, ['name'] ise bir sözlük anahtarına işaret eder.
Liste indeksi, sözlük anahtarı ve iç içe veri yapıları nasıl ayrılır?

Liste, elemanları sıralı biçimde tutar ve erişim için konum kullanır. Sözlük ise anahtar ve değer çiftlerinden oluşur; erişim anahtarla yapılır. Bu yüzden students[0] bir listedeki ilk kaydı, student['name'] ise bir sözlükteki name anahtarının değerini ifade eder.
İç içe yapılarda erişim adımları soldan sağa ilerler. Önce ilk köşeli parantez uygulanır, ardından ortaya çıkan değerin türüne göre ikinci erişim yapılır. students[0] bir sözlük döndürüyorsa, bu sözlüğün adına ulaşmak için students[0]['name'] yazılır. Dış yapı sözlük ve kayıt anahtarı 'ada' ise doğru ifade students['ada']['name'] olur.
| Veri yapısı | Geçerli erişim biçimi | Sık yapılan yanlış varsayım | Bir sonraki erişimde beklenen tür |
|---|---|---|---|
| Liste | students[0] |
students['name'] ile alan adına ulaşılacağını sanmak |
İlk erişimden sonra listenin eleman türü, örneğin dict |
| Sözlük | student['name'] |
student[0] ile ilk kaydın alınacağını sanmak |
Anahtarın değer türü, örneğin str |
| Liste içindeki sözlük | students[0]['name'] |
Listenin doğrudan 'name' anahtarına sahip olduğunu sanmak |
students[0] sonrası dict, sonrasında değer türü |
| Sözlük içindeki kayıt | students['ada']['name'] |
students[0] ile ilk kayda ulaşılacağını sanmak |
students['ada'] sonrası dict, sonrasında genellikle str |
Dolayısıyla doğru erişim ifadesi, yalnızca almak istediğin alana değil, o alana ulaşmadan önceki her katmanın türüne bağlıdır. İlk köşeli parantezden sonra bir liste mi, sözlük mü elde edildiğini belirlemek, bu hatanın kaynağını bulmanın en kısa yoludur.
type() ile gerçek veri yapısını ve JSON benzeri dış katmanı incele

Hatalı erişimi düzeltmenin en güvenli yollarından biri, değişkenin yapısını varsaymak yerine type() ile incelemektir. JSON benzeri veriler dışarıdan bakıldığında benzer görünse de dış katmanları liste veya sözlük olabilir. İç katmanlarda ise metin, sayı, liste ya da başka bir sözlük bulunabilir.
Aşağıdaki örnekte dış yapı bir listedir. Listenin ilk elemanı sözlük, sözlükteki courses değeri ise yeniden listedir:
payload = [
{'name': 'Ada', 'courses': ['Python']}
]
print(type(payload).__name__)
print(type(payload[0]).__name__)
print(type(payload[0]['courses']).__name__)
Beklenen çıktı:
list
dict
list
İlk satır dış yapının list olduğunu, ikinci satır listedeki bir kaydın dict olduğunu, üçüncü satır ise courses alanının list olduğunu gösterir. Bu nedenle erişim sırası da veri yapısına uygun kurulmalıdır: önce liste için sayı, sonra sözlük için anahtar kullanılır.
Dış yapı sözlük olduğunda ilk erişim bir anahtarla başlamalıdır. Örneğin aşağıdaki yapıda öğrenci listesi students anahtarının altındadır:
payload = {
'students': [
{'name': 'Ada'}
]
}
print(payload['students'][0]['name'])
Beklenen çıktı:
Ada
Bu yapıda payload[0] yazmak yerine payload['students'] ile ilgili alana ulaşılır. Çünkü dış katman sözlüktür ve kayıtlar doğrudan sayısal sırayla değil, bir anahtarın değeri olarak tutulur.
Öğrenci verisindeki hatalı erişimi iki doğru modelle düzelt
Aynı öğrenci bilgisi farklı veri modelleriyle tutulabilir. Doğru erişim ifadesi, öğrencilerin listenin elemanları mı yoksa sözlüğün anahtarları mı olduğuna bağlıdır.
Öğrenciler liste içinde sözlük olarak tutuluyorsa
Bu modelde students bir listedir. Listedeki her öğrenci ise kendi alanlarını taşıyan bir sözlüktür.
Hatalı ifade: students['name']
Düzeltilmiş ifade: students[0]['name']
students = [
{'name': 'Ada'},
{'name': 'Mert'}
]
print(students[0]['name'])
Beklenen çıktı:
Ada
Burada students[0] listenin ilk elemanını seçer. Bu eleman bir sözlük olduğu için ['name'] ile öğrencinin adına ulaşılır. Listeye metin anahtarı vermeye çalışmak, TypeError hatasına yol açar.
Öğrenciler bir anahtarla sözlükte tutuluyorsa
Bu modelde students bir sözlüktür. Öğrencinin kaydına ulaşmak için sözlükte tanımlı anahtar kullanılır.
Hatalı ifade: students[0]
Düzeltilmiş ifade: students['ada']['name']
students = {
'ada': {'name': 'Ada'}
}
print(students['ada']['name'])
Beklenen çıktı:
Ada
Bu kez students[0] bir sıra numarasıyla kayıt arar. Oysa kayıt ada anahtarıyla tutulduğu için erişim bu anahtarla başlamalıdır. Kısacası liste modelinde önce sayısal indeks, sözlük modelinde önce anahtar kullanılır. Hangi ifadenin doğru olduğunu belirleyen şey hata mesajı değil, verinin gerçek yapısıdır.
Dört soruluk kontrol listesiyle erişim ifadesini seç
Birden fazla köşeli parantez içeren ifadeyi tek işlem olarak değil, birbirini izleyen erişim adımları olarak oku. Her adımda şu dört soruyu kullan:
- Dış yapı nedir, liste mi sözlük mü?
type(data)ile başlangıçtaki yapıyı incele. İlk erişim adımını bu yapıya göre seç. - Erişim ifadesindeki değer hangi türdedir, tam sayı mı metin mi?
0bir tam sayı,'students'ise metindir. Bir metin anahtarını liste indeksi yerine kullanma. - Beklenen kayıt veri yapısının hangi katmanında bulunur? Öğrenci kaydının doğrudan dış listede mi, yoksa bir anahtarın altındaki listede mi olduğunu belirle. Aradaki katmanları atlama.
- Bir sonraki erişim adımı hangi veri türünü gerektirir? Ara sonuç listeyse tam sayı indeksi veya dilim kullan. Sözlükse o sözlükteki bir anahtarla ilerle.
Üç erişim ifadesini adım adım değerlendir
Aşağıdaki kod önce bir listeyle, ardından öğrencileri bir anahtar altında tutan sözlükle çalışır. İkinci atamada data değişkeninin dış yapısı değişir:
data = [{'name': 'Ece'}]
print(data[0]['name'])
data = {'students': [{'name': 'Ece'}]}
print(data['students'][0])
print(data['students'][0]['name'])
Beklenen çıktı:
Ece
{'name': 'Ece'}
Ece
data[0]['name']: İlk modelde dış yapı listedir. Tam sayı olan 0, ilk öğrenci sözlüğünü seçer. Ara sonuç sözlük olduğundan 'name' anahtarıyla devam eder, öğrencinin adına ulaşırsın.
data['students'][0]: İkinci modelde dış yapı sözlüktür. Metin anahtarı 'students', içteki listeyi verir. Ardından tam sayı olan 0, bu listedeki ilk kaydı seçer. Sonuç, öğrenci adını içeren sözlüğün tamamıdır.
data['students'][0]['name']: İlk iki adım öğrenci sözlüğüne ulaşır. Bir sonraki erişim bu sözlük üzerinde gerçekleştiği için 'name' anahtarını kullanırsın. Böylece kaydın tamamı yerine 'Ece' metnini elde edersin.
Liste ve sözlük ayrımını farklı sorularla pekiştirmek için Python bilgi testini kullanabilirsin.
Her köşeli parantezde elindeki yapıyı yeniden değerlendir. İndeksi veya anahtarı o yapıyla eşleştirmek, erişim ifadesinin hangi adımında sorun oluştuğunu belirlemene yardımcı olur.