Dasar

Dictionary di Python (dict): membuat, metode, perulangan, pengurutan dan frozendict

Diperbarui: · Skillaria.Top

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

MetodeFungsi
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:

  • frozendict mewarisi dari object, bukan dari dict, sehingga isinstance(cfg, dict) bernilai False. Untuk memeriksa «dict apa pun», gunakan collections.abc.Mapping atau isinstance(x, (dict, frozendict)).
  • Ia bisa di-hash hanya jika kunci dan nilainya bisa di-hash: frozendict(a=[1]) bisa dibuat, tetapi hash() akan gagal. Sifat tidak bisa diubahnya dangkal, seperti tuple.
  • Urutannya tersimpan, tetapi == tidak memperhatikannya.
  • json.dumps, pickle, dan copy memahami frozendict.

Kesalahan umum

  • KeyError saat membaca — gunakan get atau cek dengan in.
  • List sebagai kunci — ubah menjadi tuple: d[tuple(lst)].
  • Mengubah dict di dalam perulangan — ulangi list(d).
  • Mengira penugasan membuat salinan — gunakan copy() atau deepcopy.
  • {} 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.

Pelajari topik ini lewat video

Topik ini dibahas mendalam dengan praktik di kursus “Python 3.15: от новичка до профи”.

Ke kursus