Menghitung frekuensi, mengelompokkan transaksi per pelanggan, menjaga riwayat terakhir — semuanya bisa ditulis dengan dict dan if, tetapi kodenya penuh pola berulang. Module collections menyediakan container khusus yang menghapus pola-pola tersebut. Pada Chapter ini kita bahas lima container beserta kapan masing-masing layak dipilih, melengkapi pemahaman dict dasar dari Chapter Dictionary.
Counter: Menghitung Frekuensi #
Class Counter adalah dictionary yang nilainya otomatis menjadi jumlah kemunculan:
from collections import Counter
suara = ["siti", "budi", "siti", "andi", "siti", "budi"]
hasil_suara = Counter(suara)
print(hasil_suara)
print(hasil_suara.most_common(2))Output yang Dihasilkan:
Counter({'siti': 3, 'budi': 2, 'andi': 1})
[('siti', 3), ('budi', 2)]Membuat Counter dari list langsung menghitung frekuensi setiap elemen. Method most_common(k) lalu menjawab pertanyaan “siapa dua teratas” dalam satu panggilan — pola yang dikenal sebagai top-k — tanpa kita menulis loop penghitung manual.
defaultdict: Pengelompokan Tanpa Setdefault #
Class defaultdict menghilangkan pengecekan if nama not in dict saat membangun kelompok. Kita cukup menentukan factory nilai bawaan saat konstruksi:
from collections import defaultdict
penjualan = [("Budi", 120), ("Siti", 200), ("Budi", 80), ("Andi", 150)]
per_sales = defaultdict(list)
for nama, nilai in penjualan:
per_sales[nama].append(nilai)
print(dict(per_sales))
total_per_sales = defaultdict(int)
for nama, nilai in penjualan:
total_per_sales[nama] += nilai
print(dict(total_per_sales))Output yang Dihasilkan:
{'Budi': [120, 80], 'Siti': [200], 'Andi': [150]}
{'Budi': 200, 'Siti': 200, 'Andi': 150}Mari kita bedah dua pola di atas:
- Baris 5 (
defaultdict(list)): saat key baru diakses,defaultdictotomatis membuat list kosong, sehinggaper_sales[nama].append(nilai)langsung berjalan tanpa pengecekan apakah key sudah ada. - Baris 11 (
defaultdict(int)): nilai bawaanint()adalah0, sehingga operasi+= nilaipada key baru dimulai dari nol. Pola ini ideal untuk akumulasi total per kelompok.
deque: Antrian Dua Arah #
Class deque (double-ended queue) menambah dan menghapus elemen di kedua ujung dengan kompleksitas O(1), berbeda dengan list yang operasi pop(0)-nya O(n) karena harus menggeser seluruh elemen. Parameter maxlen membuatnya cocok untuk riwayat terbatas:
from collections import deque
riwayat = deque(maxlen=3)
for halaman in ["beranda", "produk", "keranjang", "pembayaran"]:
riwayat.append(halaman)
print(list(riwayat))
riwayat.appendleft("promo")
print(list(riwayat))Output yang Dihasilkan:
['produk', 'keranjang', 'pembayaran']
['promo', 'produk', 'keranjang']Karena maxlen=3, penambahan "pembayaran" otomatis membuang "beranda" yang paling lama. Method appendleft("promo") kemudian menyisipkan di depan sambil membuang elemen paling kanan ("pembayaran") — antrian tetap berisi tepat tiga halaman.
OrderedDict dan ChainMap #
Sejak Python 3.7, dict bawaan menjamin urutan penyisipan, sehingga OrderedDict jarang dibutuhkan. Dua fitur yang masih membuatnya relevan: method move_to_end() untuk memindahkan key, dan perbandingan == yang memperhatikan urutan (dua OrderedDict dengan isi sama tetapi urutan beda dianggap tidak sama).
Class ChainMap merangkai beberapa dictionary menjadi satu tampilan; pencarian key dilakukan dari peta pertama:
from collections import ChainMap
config_default = {"debug": False, "port": 8000, "host": "127.0.0.1"}
config_lokal = {"debug": True}
config_aktif = ChainMap(config_lokal, config_default)
print(config_aktif["debug"])
print(config_aktif["port"])Output yang Dihasilkan:
True
8000Key "debug" diambil dari config_lokal yang berada di depan, sedangkan key "port" yang tidak ada di sana diteruskan ke config_default. Pola ini tepat untuk berlapis konfigurasi: default aplikasi → environment → argumen command line, tanpa menggabungkan dictionary secara fisik.
Memilih Container yang Tepat #
| Container | Pertanyaan kunci | Contoh nyata |
|---|---|---|
Counter | Perlu menghitung atau memberi peringkat? | Top produk terlaris |
defaultdict | Perlu mengelompokkan atau mengakumulasi? | Penjualan per sales |
deque | Perlu antrian/riwayat dengan ujung cepat? | Riwayat navigasi |
OrderedDict | Perlu memindah urutan atau membandingkan urutan? | Cache LRU manual |
ChainMap | Perlu berlapis konfigurasi dengan prioritas? | Default + override lokal |
Kelima container ini bekerja mulus dengan iterator, dan pada Chapter itertools kita akan melihat bagaimana combinatoric seperti groupby() menghasilkan data yang siap ditampung langsung oleh defaultdict.