pythondictMenengah5 mnt baca

Dict Lanjutan di Python

Kuasai get(), keys/values/items, dan dict bersarang untuk menangani data ala JSON tanpa takut KeyError.

Analogi singkat: kartu nama bertumpuk

Kalau dict dasar itu seperti satu kartu nama (nama jadi kunci, nomor jadi nilai), dict lanjutan itu seperti setumpuk kartu nama yang saling merujuk: kartu perusahaan berisi kartu kontak, kartu kontak berisi kartu alamat. Kamu harus bisa menyelam ke dalamnya dengan aman, tanpa program meledak karena satu kunci hilang.

get(): akses aman tanpa KeyError

python
siswa = {"nama": "Rina", "nilai": 85}

# akses langsung: error kalau kunci tidak ada
# print(siswa["kelas"])  # KeyError!

# get(): kembalikan None (atau default) kalau kunci hilang
print(siswa.get("kelas"))              # None
print(siswa.get("kelas", "belum ada"))  # belum ada

# pola praktis: hitung kemunculan tanpa if
kata = {}
for w in ["apel", "mangga", "apel", "apel"]:
    kata[w] = kata.get(w, 0) + 1
print(kata)  # {'apel': 3, 'mangga': 1}

keys(), values(), items()

python
stok = {"kopi": 20, "teh": 35, "roti": 12}

for kunci in stok.keys():
    print("kunci:", kunci)

for nilai in stok.values():
    print("nilai:", nilai)

# items() paling sering dipakai: kunci DAN nilai sekaligus
for nama, jumlah in stok.items():
    print(nama, "tersisa", jumlah)

Catatan teknis: keys(), values(), items() mengembalikan view yang mengikuti perubahan dict. Kalau butuh snapshot beku, bungkus dengan list(...).

Dict bersarang: data ala JSON

API dan file JSON hampir selalu berbentuk dict di dalam dict. Akses bertingkat dengan get berantai supaya aman:

python
pengguna = {
    "nama": "Dedi",
    "kontak": {
        "email": "[email protected]",
        "telepon": "08123456789",
    },
    "pesanan": [
        {"barang": "kopi", "qty": 2},
        {"barang": "roti", "qty": 1},
    ],
}

# akses bertingkat
print(pengguna["kontak"]["email"])  # [email protected]

# versi aman: berantai dengan get
kota = pengguna.get("alamat", {}).get("kota", "tidak diketahui")
print(kota)  # tidak diketahui

# loop list of dict di dalamnya
for p in pengguna["pesanan"]:
    print(p["barang"], "x", p["qty"])

Contoh 1: agregasi penjualan per kategori

python
transaksi = [
    {"kategori": "minuman", "nominal": 15000},
    {"kategori": "makanan", "nominal": 12000},
    {"kategori": "minuman", "nominal": 8000},
    {"kategori": "makanan", "nominal": 20000},
]

rekap = {}
for t in transaksi:
    k = t["kategori"]
    rekap[k] = rekap.get(k, 0) + t["nominal"]

for kategori, total in rekap.items():
    print(kategori, ": Rp", total)
# minuman : Rp 23000
# makanan : Rp 32000

Ini pola paling umum di analisis data: kelompokkan berdasarkan satu kunci, jumlahkan nilainya.

Contoh 2: bangun struktur nested dari data datar

python
# data datar dari CSV -> ubah jadi nested per kota
baris = [
    ("Jakarta", "Rina", 25),
    ("Bandung", "Budi", 30),
    ("Jakarta", "Sari", 22),
]

per_kota = {}
for kota, nama, umur in baris:
    per_kota.setdefault(kota, []).append({"nama": nama, "umur": umur})

print(per_kota["Jakarta"])
# [{'nama': 'Rina', 'umur': 25}, {'nama': 'Sari', 'umur': 22}]

Catatan teknis: setdefault(kunci, default) mengembalikan nilai yang ada, atau menyisipkan default lalu mengembalikannya. Pasangan serasi get untuk pola akumulasi.

Kesalahan umum

SALAH: asumsi kunci selalu ada

python
print(data["email"])  # KeyError kalau baris datanya tidak punya email

BENAR: get dengan default yang masuk akal

python
print(data.get("email", ""))

SALAH: mengubah ukuran dict saat iterasi

python
for k in stok:
    if stok[k] == 0:
        del stok[k]  # RuntimeError: dictionary changed size during iteration

BENAR: iterasi atas salinan daftar kunci

python
for k in list(stok.keys()):
    if stok[k] == 0:
        del stok[k]

Tantangan

Rekap Nilai per Kelas

Diberi list dict berisi nama, kelas, dan nilai. Bangun dict rekap berisi total nilai per kelas memakai get(), lalu cetak tiap kelas dan totalnya.