flowchart TD
A["students: list"] --> B["record 1: dict"]
A --> C["record 2: dict"]
A --> D["record 3: dict"]
B --> B1["number"]
B --> B2["name"]
B --> B3["grade"]
Kayıtlar ve iç içe veri yapıları
Programlama Temelleri dersinde liste içinde sözlük gibi iç içe yapılarla tanıştınız. Bu hafta aynı söz dizimini yeniden öğrenmeyeceğiz. Sorumuz şu:
Aynı kayıt kümesini farklı biçimlerde düzenlersek hangi işlemler kolaylaşır, hangileri zorlaşır?
Kayıt (record), aynı şeye ait bilgilerin bir arada tutulduğu veridir: bir öğrencinin numarası, adı ve notu gibi. Bu derste sınıf yazmadığımız için kayıtları çoğunlukla sözlükle tutacağız. Kayıtları bir araya toplayan dış yapı ise probleme göre değişecek: bazen liste, bazen sözlük.
1 Bu hafta neleri yapabilmelisiniz?
Bölümün sonunda:
- Bir kaydı sözlükle temsil edebilmeli,
- Çok sayıda kaydı liste içinde sözlüklerle düzenleyebilmeli,
- Aynı kayıtlara öğrenci numarası gibi bir kimlikten ulaştıran bir
dictoluşturabilmeli, - Gruplama için
dict+listyapısını kullanabilmeli, - Kayıt ekleyebilmeli, güncelleyebilmeli, filtreleyebilmeli ve özetleyebilmeli,
- Aynı veriyi farklı biçimlerde tutmanın hangi işlemleri kolaylaştırdığını açıklayabilmeli,
- İç içe yapılarda sığ kopyayı ve aynı nesnenin iki yerden görülmesini fark edebilmelisiniz.
2 Bir kayıt: alan adları neden önemlidir?
Bir öğrenciyi tek tek değişkenlerle tutabiliriz:
number = 102
name = "Bora"
department = "Yazılım"
grade = 78Ama koda bakınca bu değerlerin aynı öğrenciye ait olduğu anlaşılmaz. Sözlükte bu bağ açıkça görülür:
Sözlükte her değer, ait olduğu alanın (kaydın name, grade gibi bir parçasının) adıyla birlikte durur.
3 Temsil 1: liste içinde kayıtlar
Bir sınıftaki öğrencileri liste içinde sözlüklerle tutabiliriz:
Bu düzen özellikle şu işler için uygundur:
- Kayıtların sırasını koruma,
- Bütün kayıtları dolaşma,
- Filtreleme,
- Sıralı rapor hazırlama.
4 Listede kimliğe göre arama
Öğrenci numarasına göre kayıt bulmak için listeyi dolaşabiliriz:
Bu çözüm yanlış değil. Ama aynı arama binlerce kez yapılacaksa her seferinde listeyi baştan dolaşmak yavaş kalabilir.
5 Temsil 2: kimliğe göre indekslenmiş sözlük
Aynı kayıtları, numarayı anahtar yapan bir sözlükte de tutabiliriz:
Bu temsilde “102 numaralı öğrenci kim?” sorusunun kod karşılığı doğrudan students_by_number[102] olur.
5.1 Aynı veri, farklı güçlü yanlar
| Temsil | Güçlü olduğu işlem |
|---|---|
list[dict] |
sırayla dolaşma, filtreleme, raporlama |
dict[id -> record] |
kimliğe göre sık erişim |
Hangi düzenin daha iyi olduğu probleme bağlıdır. Dış yapıyı seçerken en sık yapılan işleme bakın.
6 Temsil 3: dict + list ile gruplama
Bazen anahtardan tek bir kayda değil, bir kayıt grubuna ulaşmak isteriz. Örneğin öğrencileri bölüme göre gruplayalım:
Burada dış sözlüğün her anahtarı bir bölümün adıdır. O anahtarın değeri olan liste de bölümdeki öğrencileri tutar.
7 Üç temsili birlikte görelim
flowchart LR
R["Aynı kayıt kümesi"] --> L["list[dict]"]
R --> I["dict[id → record]"]
R --> G["dict[group → list[record]]"]
L --> L1["sıra / filtre / rapor"]
I --> I1["kimliğe göre erişim"]
G --> G1["gruba göre erişim"]
Gerçek programlarda aynı kayıtlar bu düzenlerden birkaçında aynı anda tutulabilir.
8 Aynı kayda iki yapıdan ulaşmak
Listedeki kayıtlar için numaraya göre bir sözlüğü sonradan da oluşturabiliriz:
Neden listedeki kayıt da değişti? Çünkü students listesi ile by_number sözlüğü aynı öğrenci sözlüğünü gösteriyor.
Bu işe yarayabilir: aynı kaydı kopyalamadan ona iki farklı yoldan ulaşırız. Ama bağımsız bir kopya bekliyorsak hataya yol açabilir.
9 Filtreleme kalıbı
Belirli koşula uyan kayıtları yeni bir listede toplayalım:
Filtrelerken bütün kayıtlara bakmak gerektiği için list[dict] uygun bir seçimdir.
10 Alıştırma: düşük stoklu ürünler
stock değeri 10’dan küçük ürünlerin adlarını low_stock listesine ekleyin.
Beklenen çıktı:
['Defter', 'Silgi']
if product["stock"] < 10: koşulundan sonra low_stock.append(...) kullanın.
for product in products:
if product["stock"] < 10:
low_stock.append(product["name"])11 Alıştırma: kimliğe göre indeks oluştur
Aşağıdaki ürünleri, code alanı anahtar olacak biçimde by_code sözlüğüne yerleştirin.
Sözlüğün anahtarı product["code"], değeri ise product kaydının kendisi olabilir.
for product in products:
by_code[product["code"]] = product12 Özetleme
Kayıtlardaki sayısal alanları özetlemek için biriktirici kalıbını kullanabiliriz:
Burada toplamın kendisinden çok kalıp önemli: bütün kayıtları dolaşıp her birinden aynı alanı alıyoruz.
13 İç içe yapıları okurken adım adım düşünün
Şu ifadeyi inceleyelim:
students[1]["courses"][0]Bunu tek seferde değil adım adım okuyun:
students[1]→ ikinci öğrenci kaydı,["courses"]→ o kaydın ders listesi,[0]→ ilk ders.
Böyle okumak, iç içe yapılarda yanlış indeks ya da yanlış anahtar yazma hatalarını azaltır.
14 Sığ kopya tekrar karşımıza çıkıyor
.copy() yalnız dıştaki sözlüğü kopyalar; içteki tags listesi iki kayıt arasında ortak kalır. Bu, 2. haftada gördüğümüz sığ kopyanın kayıtlardaki karşılığıdır.
15 Küçük karar çalışması
Aynı öğrenci verisi için aşağıdaki ihtiyaçların her birinde hangi düzeni seçerdiniz?
- Bütün öğrencileri kayıt sırasıyla ekranda göstermek.
- Öğrenci numarasına göre saniyede çok sayıda sorgu yapmak.
- Bölüm adına göre o bölümdeki öğrencilerin tamamına ulaşmak.
Seçenekler:
A. list[dict]
B. dict[number -> record]
C. dict[department -> list[record]]
Yanıtınıza yalnızca yapının adını değil, hangi işlemi kolaylaştırdığını da yazın.
16 Bölüm özeti
- Bir kaydı sözlükle tutabiliriz.
list[dict], çok sayıda kaydı sırayla dolaşmak, filtrelemek ve raporlamak için uygundur.- Aynı kayıtları
dict[id -> record]biçiminde indekslemek kimliğe göre sık erişimi kolaylaştırır. dict[group -> list[record]]gruplama problemlerine uygundur.- Aynı kayıt nesnesini birden çok koleksiyon gösterebilir.
- Düzeni söz dizimine göre değil, yapılacak işlemlere göre seçeriz.
- İç içe yapılarda sığ kopyaya dikkat edin: içteki nesneler ortak kalır.
17 Kendinizi kontrol edin
list[dict]hangi işlemler için uygundur?- Öğrencilere numarayla çok sık erişmek gerekiyorsa dış yapıyı nasıl değiştirirsiniz?
- Öğrencileri bölüme göre gruplamak için hangi yapıları birlikte kullanırsınız?
studentslistesi ileby_numbersözlüğü aynı kayıt nesnesini gösteriyorsa birindeki değişiklik neden diğerinde görünür?- Filtreleme için neden çoğu zaman bütün kayıtları dolaşmak gerekir?
- Sığ kopyası alınmış bir sözlüğün içindeki liste neden iki kopyada ortak kalır?