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

URL: https://skillaria.top/id/guides/python/dict-python

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:

- `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».

## FAQ

**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.


---
Source: Skillaria.Top (https://skillaria.top)
