Dictionary di Python (dict): membuat, metode, perulangan, pengurutan dan frozendict
Dictionary di Python (dict) adalah kumpulan pasangan kunci dan nilai yang bisa diubah, dan nilai bisa dicari berdasarkan kunci hampir seketika; dibuat dengan kurung kurawal, misalnya {"kopi": 250}, atau fungsi dict(). Kunci harus unik dan bisa di-hash, urutan penyisipan terjaga sejak Python 3.7, dan di 3.15 tersedia varian bawaan yang tidak bisa diubah, yaitu frozendict.
Dictionary di Python (dict) adalah kumpulan pasangan «kunci — nilai», tempat nilai bisa ditemukan lewat kuncinya hampir seketika, berapa pun jumlah datanya. Jika Anda ingin menghitung pengeluaran per kategori, menyimpan pengaturan, atau mencari pengguna berdasarkan id dengan cepat, dict adalah jawabannya. Berikut semua yang perlu diketahui tentang dict Python: membuat, metode, perulangan, pengurutan, penggabungan, dan hal baru di 3.15 — frozendict.
Apa itu dictionary di Python
Dictionary menyimpan pasangan dengan kunci yang unik: jika Anda menulis nilai dengan kunci yang sudah ada, nilai lama akan digantikan. Secara internal ia adalah tabel hash, sehingga pencarian, penambahan, dan penghapusan berdasarkan kunci berjalan rata-rata dalam waktu konstan, bukan dengan menelusuri satu per satu.
Kunci hanya boleh objek yang bisa di-hash: string, angka, tuple dari nilai yang tidak bisa diubah. List tidak bisa menjadi kunci — Anda akan mendapat TypeError: unhashable type: 'list'. Nilainya bebas, termasuk dict atau list lain.
Sejak Python 3.7, dict dijamin mengingat urutan penyisipan: saat diulang, kuncinya keluar sesuai urutan saat ditambahkan.
Cara membuat dict
Ada beberapa cara membuat dict, dan semuanya muncul di kode nyata.
spent = {"Makan": 1200, "Taksi": 450} # literal
empty = {} # dict kosong
also_empty = dict() # sama, lewat fungsi dict
user = dict(name="Rina", age=30) # argumen bernama
pairs = dict([("a", 1), ("b", 2)]) # dari list pasangan
keys = dict.fromkeys(["x", "y"], 0) # {'x': 0, 'y': 0}
Perhatikan: kurung kurawal kosong {} membuat dict kosong, bukan set. Set kosong hanya dibuat dengan set().
Cara praktis membuat dict dari dua list adalah zip:
names = ["Makan", "Taksi", "Bioskop"]
sums = [1200, 450, 600]
spent = dict(zip(names, sums))
print(spent) # {'Makan': 1200, 'Taksi': 450, 'Bioskop': 600}
Akses lewat kunci: d[k] dan get
Nilai dibaca dengan kurung siku. Jika kuncinya tidak ada, Python melempar KeyError. Untuk menghindari error itu, gunakan metode get: ia mengembalikan None atau nilai bawaan yang Anda tentukan.
spent = {"Makan": 1200}
print(spent["Makan"]) # 1200
print(spent.get("Bioskop")) # None
print(spent.get("Bioskop", 0)) # 0
spent["Bioskop"] # KeyError: 'Bioskop'
Untuk mengecek apakah sebuah kunci ada, gunakan operator in: "Makan" in spent bernilai True. Operator ini memeriksa kunci, bukan nilai. Untuk nilai, tulis 1200 in spent.values().
Menambah, mengubah, dan menghapus
Menambah atau memperbarui entri cukup dengan satu baris penugasan. Untuk penghitungan, pola dengan get sangat berguna:
spent = {}
for category, amount in [("Makan", 250), ("Taksi", 300), ("Makan", 400)]:
spent[category] = spent.get(category, 0) + amount
print(spent) # {'Makan': 650, 'Taksi': 300}
Menghapus kunci bisa dengan del d[k] (melempar KeyError jika kunci tidak ada) atau d.pop(k, default), yang sekaligus mengembalikan nilainya. Mengosongkan seluruh dict dilakukan dengan d.clear(). Panjang dict, yaitu jumlah pasangannya, didapat dengan len(d).
Metode dict: contekan
| Metode | Fungsi |
|---|---|
get(k, default) | nilai berdasarkan kunci, atau default tanpa error |
setdefault(k, default) | mengembalikan nilai; jika kunci tidak ada, menuliskan default dulu |
update(other) | menambahkan dan menimpa pasangan dari dict lain |
pop(k, default) | menghapus kunci dan mengembalikan nilainya |
popitem() | menghapus dan mengembalikan pasangan yang terakhir ditambahkan |
keys(), values(), items() | tampilan kunci, nilai, dan pasangan |
copy() | salinan dangkal |
clear() | mengosongkan dict |
fromkeys(keys, value) | dict baru dengan nilai yang sama untuk semua kunci |
setdefault: mengisi dict dengan list
Metode setdefault sangat membantu ketika nilainya berupa list dan Anda ingin mengelompokkan data:
groups = {}
for item, cat in [("kopi", "Makan"), ("kereta", "Transportasi"), ("pizza", "Makan")]:
groups.setdefault(cat, []).append(item)
print(groups) # {'Makan': ['kopi', 'pizza'], 'Transportasi': ['kereta']}
update: memperbarui dict
update mengubah dict di tempat: kunci baru ditambahkan, kunci yang sama ditimpa.
cfg = {"debug": False, "lang": "id"}
cfg.update({"debug": True, "theme": "dark"})
print(cfg) # {'debug': True, 'lang': 'id', 'theme': 'dark'}
defaultdict: dict dengan nilai bawaan
collections.defaultdict adalah subkelas dict yang, saat kunci yang belum ada diakses, langsung membuat nilai baru memakai fungsi pembuatnya. Kode penghitungan dan pengelompokan menjadi lebih pendek.
from collections import defaultdict
spent = defaultdict(int)
for cat, amount in [("Makan", 250), ("Taksi", 300), ("Makan", 400)]:
spent[cat] += amount
print(dict(spent)) # {'Makan': 650, 'Taksi': 300}
groups = defaultdict(list)
groups["Makan"].append("kopi")
Untuk sekadar menghitung kemunculan, ada juga collections.Counter: Counter(["a", "b", "a"]) menghasilkan Counter({'a': 2, 'b': 1}).
Perulangan dict dengan for
Perulangan for pada dict secara default melewati kunci. Untuk mendapatkan kunci dan nilai sekaligus, ulangi items() — ini pola yang paling sering dipakai.
spent = {"Makan": 650, "Taksi": 300}
for cat in spent: # kunci
print(cat)
for amount in spent.values(): # nilai
print(amount)
for cat, amount in spent.items(): # pasangan
print(f"{cat}: {amount} Rp")
Mengubah ukuran dict saat sedang diulang tidak diperbolehkan — akan muncul RuntimeError: dictionary changed size during iteration. Jika perlu menghapus sebagian kunci, ulangi salinannya: for k in list(d):.
Menampilkan dict di layar
print(d) mencetak dict dalam satu baris. Untuk dict yang besar atau bersarang, lebih nyaman memakai modul pprint atau json.dumps(d, ensure_ascii=False, indent=2) — datanya akan tampil berjenjang dengan huruf Cyrillic dan Latin tanpa escape.
Mengurutkan dict
Dict itu sendiri tidak bisa diurutkan di tempat, karena tidak punya metode sort. Mengurutkan dict berarti membuat dict baru dari pasangan yang sudah diurutkan dengan sorted.
spent = {"Taksi": 300, "Makan": 650, "Bioskop": 120}
by_key = dict(sorted(spent.items()))
print(by_key) # {'Bioskop': 120, 'Makan': 650, 'Taksi': 300}
by_value = dict(sorted(spent.items(), key=lambda p: p[1], reverse=True))
print(by_value) # {'Makan': 650, 'Taksi': 300, 'Bioskop': 120}
Jika Anda hanya butuh top-N kategori, jangan ubah hasilnya kembali menjadi dict: sorted(spent.items(), key=lambda p: p[1], reverse=True)[:2] mengembalikan list pasangan.
Untuk mengurutkan list dict berdasarkan sebuah field: sorted(users, key=lambda u: u["age"]).
Menggabungkan dan menjumlahkan dict
Sejak Python 3.9, dict digabung dengan operator |, dan |= memperbarui dict di tempat. Jika kuncinya sama, operand kanan yang menang.
a = {"x": 1, "y": 2}
b = {"y": 20, "z": 3}
print(a | b) # {'x': 1, 'y': 20, 'z': 3}
print({**a, **b}) # sama, lewat pembongkaran
a |= b # sama seperti a.update(b)
Perhatikan: a + b untuk dict tidak berfungsi dan menghasilkan TypeError. Jika memang ingin menjumlahkan nilai untuk kunci yang sama, gunakan Counter: Counter(a) + Counter(b).
Pembongkaran dict
Dua tanda bintang ** membongkar dict menjadi argumen bernama untuk fungsi, atau menjadi dict lain:
def greet(name, city):
return f"{name} dari {city}"
data = {"name": "Rina", "city": "Bandung"}
print(greet(**data)) # Rina dari Bandung
Dict comprehension
Dict comprehension membangun dict dalam satu baris dari sembarang urutan:
squares = {n: n * n for n in range(5)}
print(squares) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
big = {k: v for k, v in spent.items() if v > 200}
inverted = {v: k for k, v in {"a": 1, "b": 2}.items()}
print(inverted) # {1: 'a', 2: 'b'}
Contoh terakhir adalah cara membalik dict dengan menukar kunci dan nilai. Ini hanya berfungsi jika nilainya unik dan bisa di-hash; kalau tidak, sebagian pasangan akan hilang.
Dict bersarang
Nilai bisa berupa dict lain. Dengan cara ini struktur seperti respons JSON dari API atau dict pengguna di dalam dict dimodelkan.
users = {
101: {"name": "Rina", "skills": ["python", "sql"]},
102: {"name": "Budi", "skills": ["go"]},
}
print(users[101]["skills"][0]) # python
print(users.get(103, {}).get("name")) # None, tanpa KeyError
Menyalin dict: salinan dan nama kedua
Penugasan b = a tidak menyalin dict, hanya memberi nama kedua pada objek yang sama. Jika Anda mengubah lewat b, perubahan juga terlihat di a. Hal yang sama terjadi saat dict dikirim ke fungsi: fungsi menerima referensi ke objek yang sama dan bisa merusaknya tanpa diketahui.
import copy
a = {"limits": [0, 500]}
b = a.copy() # salinan dangkal
b["limits"].append(1000) # list bersarang ternyata dipakai bersama!
print(a) # {'limits': [0, 500, 1000]}
c = copy.deepcopy(a) # salinan penuh yang independen
Membandingkan dict
Operator == membandingkan dict berdasarkan isinya: sama jika semua pasangannya cocok. Urutan kunci tidak ikut dihitung: {"a": 1, "b": 2} == {"b": 2, "a": 1} bernilai True. Untuk mencari kunci yang sama di dua dict, gunakan operasi himpunan pada tampilan kunci: a.keys() & b.keys().
Dict bertipe: anotasi
Anotasi untuk dict ditulis dict[str, int]. Jika dict punya sekumpulan field tetap dengan tipe berbeda, TypedDict dari modul typing lebih cocok:
from typing import TypedDict
class User(TypedDict):
name: str
age: int
u: User = {"name": "Rina", "age": 30}
Anotasi tidak diperiksa saat program berjalan; yang membacanya adalah IDE dan analisis statis seperti mypy.
Dict yang tidak bisa diubah: frozendict di Python 3.15
Python 3.15 memperkenalkan tipe bawaan frozendict (PEP 814): tidak perlu impor, dan upaya mengubahnya langsung berakhir dengan TypeError. Sebelumnya, dict yang tidak bisa diubah harus dibuat dengan pembungkus dari modul types atau paket pihak ketiga. Ini tepat untuk pengaturan bersama yang tidak boleh diubah diam-diam oleh fungsi mana pun.
config = frozendict(min_amount=0, max_amount=500)
config["max_amount"] = 1000
# TypeError: 'frozendict' object does not support item assignment
strict = config | {"max_amount": 300} # frozendict baru, yang asli tetap utuh
cache = {config: "laporan Mei"} # bisa di-hash, jadi boleh menjadi kunci
Hal penting yang perlu diketahui, sesuai materi kursus:
frozendictmewarisi dariobject, bukan daridict, sehinggaisinstance(cfg, dict)bernilaiFalse. Untuk memeriksa «dict apa pun», gunakancollections.abc.Mappingatauisinstance(x, (dict, frozendict)).- Ia bisa di-hash hanya jika kunci dan nilainya bisa di-hash:
frozendict(a=[1])bisa dibuat, tetapihash()akan gagal. Sifat tidak bisa diubahnya dangkal, seperti tuple. - Urutannya tersimpan, tetapi
==tidak memperhatikannya. json.dumps,pickle, dancopymemahami frozendict.
Kesalahan umum
- KeyError saat membaca — gunakan
getatau cek denganin. - List sebagai kunci — ubah menjadi tuple:
d[tuple(lst)]. - Mengubah dict di dalam perulangan — ulangi
list(d). - Mengira penugasan membuat salinan — gunakan
copy()ataudeepcopy. {}dipakai sebagai set kosong — itu dict kosong.
Ringkasan
Dict di Python adalah struktur data utama bahasa ini: pencarian cepat berdasarkan kunci, urutan penyisipan yang terjaga, metode praktis seperti get, setdefault, update, perulangan lewat items(), pengurutan dengan sorted, dan penggabungan dengan |. Perhatikan soal penyalinan dan kunci yang bisa di-hash, dan untuk pengaturan di Python 3.15 gunakan frozendict. Dict, list, tuple, dan set dipraktikkan dengan contoh pencatat pengeluaran di kursus «Python 3.15: dari pemula sampai mahir».
Pertanyaan umum
Bolehkah dict menyimpan nilai dengan tipe berbeda?
Boleh. Nilai dalam satu dict bisa berbeda-beda: angka, string, list, dict lain. Pembatasannya hanya untuk kunci, yang harus bisa di-hash.
Bagaimana mengetahui jumlah elemen dalam dict?
Fungsi len(d) mengembalikan jumlah pasangan kunci dan nilai. Untuk dict kosong hasilnya 0, dan dict kosong dianggap salah dalam kondisi if.
Apa bedanya dict dan defaultdict?
defaultdict adalah subkelas dict yang tidak melempar KeyError saat kunci belum ada, melainkan membuat nilai lewat fabrik, misalnya int atau list. Selebihnya perilakunya sama dengan dict biasa.
Bagaimana mendapatkan kunci berdasarkan nilainya?
Tidak ada metode langsung, jadi perlu perulangan: next((k for k, v in d.items() if v == value), None). Jika sering dicari, lebih baik buat dict terbalik dengan {v: k for k, v in d.items()}.
Bagaimana menyimpan dict ke dalam berkas?
Paling sering lewat modul json: json.dump(d, f, ensure_ascii=False, indent=2) ke berkas yang dibuka untuk menulis, dan json.load(f) untuk membaca. Kunci akan berubah menjadi string.
Topik ini dibahas mendalam dengan praktik di kursus “Python 3.15: от новичка до профи”.
Ke kursus