16. Dictionary: Memetakan Kunci ke Nilai
Di bab-bab sebelumnya, kita belajar tentang list dan tuple—koleksi yang menyimpan item dalam urutan tertentu dan memungkinkan kita mengaksesnya berdasarkan posisi. Tapi bagaimana kalau kita ingin mencari informasi berdasarkan sesuatu yang lebih bermakna daripada angka? Bagaimana kalau kita ingin menemukan nilai seorang siswa berdasarkan namanya, atau harga produk berdasarkan ID-nya, atau definisi sebuah kata berdasarkan kata itu sendiri?
Di sinilah dictionary berperan. Dictionary adalah struktur data bawaan Python (tipe dict) untuk menyimpan pasangan key-value (key-value pairs). Alih-alih mengakses item berdasarkan posisinya (seperti grades[0]), kita mengaksesnya berdasarkan key-nya (seperti grades["Alice"]). Ini membuat dictionary sangat kuat untuk mengatur dan mengambil data dalam program dunia nyata.
Bayangkan dictionary seperti kamus atau buku telepon di dunia nyata: kamu mencari sebuah kata (key) untuk menemukan definisinya (value), atau kamu mencari sebuah nama untuk menemukan nomor telepon. Dictionary Python bekerja dengan cara yang sama—mereka memetakan key ke value, memungkinkan pencarian cepat dan pengorganisasian data yang fleksibel.
16.1) Membuat Dictionary dan Mengakses Nilai
16.1.1) Apa Itu Dictionary?
Sebuah dictionary adalah koleksi pasangan key-value. Setiap key terasosiasi dengan sebuah value, dan kamu menggunakan key untuk mengambil value tersebut. Key harus unik di dalam sebuah dictionary—kamu tidak bisa punya dua entri dengan key yang sama. Namun, value boleh duplikat.
Berikut struktur dasarnya:
- Keys: pengenal unik yang digunakan untuk mencari value (seperti nama, ID, atau label)
- Values: data yang terkait dengan setiap key (seperti nilai, harga, atau deskripsi)
Dictionary bersifat:
- Mutable: kamu bisa menambahkan, mengubah, atau menghapus pasangan key-value setelah dibuat
- Unordered (di Python 3.6 dan sebelumnya) atau insertion-ordered (di Python 3.7+): Meski Python modern mempertahankan urutan saat kamu menambahkan item, kamu sebaiknya memikirkan dictionary sebagai koleksi di mana kamu mengakses item berdasarkan key, bukan berdasarkan posisi
- Dynamic: dapat bertambah dan berkurang sesuai kebutuhan
16.1.2) Membuat Dictionary Kosong dan Sederhana
Cara paling sederhana untuk membuat dictionary adalah menggunakan kurung kurawal {} dengan pasangan key-value yang dipisahkan oleh titik dua:
# Dictionary kosong
empty_dict = {}
print(empty_dict) # Output: {}
print(type(empty_dict)) # Output: <class 'dict'>
# Dictionary dengan nilai siswa
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
print(grades) # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92}
# Dictionary dengan harga produk
prices = {"apple": 0.50, "banana": 0.30, "orange": 0.75}
print(prices) # Output: {'apple': 0.5, 'banana': 0.3, 'orange': 0.75}Perhatikan sintaksnya: setiap pasangan key-value ditulis sebagai key: value, dan pasangan-pasangan dipisahkan oleh koma. Key di sini adalah string ("Alice", "apple"), dan value adalah angka, tetapi baik key maupun value bisa berupa banyak tipe yang berbeda.
Kamu juga bisa membuat dictionary menggunakan konstruktor dict():
# Menggunakan dict() dengan keyword arguments
student = dict(name="Alice", age=20, major="Computer Science")
print(student) # Output: {'name': 'Alice', 'age': 20, 'major': 'Computer Science'}
# Menggunakan dict() dengan daftar tuple
colors = dict([("red", "#FF0000"), ("green", "#00FF00"), ("blue", "#0000FF")])
print(colors) # Output: {'red': '#FF0000', 'green': '#00FF00', 'blue': '#0000FF'}Konstruktor dict() berguna ketika kamu membangun dictionary dari struktur data lain atau ketika kamu ingin menggunakan identifier Python sebagai key (tanpa tanda kutip).
16.1.3) Mengakses Nilai berdasarkan Key
Untuk mengambil value dari sebuah dictionary, gunakan tanda kurung siku dengan key:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
# Akses value satu per satu
alice_grade = grades["Alice"]
print(alice_grade) # Output: 95
bob_grade = grades["Bob"]
print(bob_grade) # Output: 87Ini adalah cara paling langsung untuk mengakses value dictionary. Namun, jika kamu mencoba mengakses key yang tidak ada, Python akan memunculkan KeyError:
grades = {"Alice": 95, "Bob": 87}
# WARNING: KeyError - for demonstration only
# print(grades["David"]) # PROBLEM: KeyError: 'David'Error ini terjadi karena "David" bukan key di dalam dictionary. Kita akan belajar cara menanganinya dengan aman di subbagian berikutnya.
16.1.4) Akses Aman dengan get()
Untuk menghindari KeyError ketika sebuah key mungkin tidak ada, gunakan metode get(). Metode ini mengembalikan None (atau nilai default yang kamu tentukan) jika key tidak ditemukan:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
# Akses aman dengan get()
alice_grade = grades.get("Alice")
print(alice_grade) # Output: 95
# Key tidak ada - mengembalikan None
david_grade = grades.get("David")
print(david_grade) # Output: None
# Berikan nilai default
david_grade = grades.get("David", 0)
print(david_grade) # Output: 0
# Menggunakan get() dalam logika kondisional
if grades.get("Eve") is None:
print("Eve tidak ada di buku nilai") # Output: Eve tidak ada di buku nilaiMetode get() lebih aman daripada akses kurung siku langsung ketika kamu tidak yakin sebuah key ada. Argumen kedua untuk get() adalah nilai default yang akan dikembalikan jika key tidak ada—kalau kamu tidak menyediakannya, default-nya adalah None.
Berikut contoh praktis yang menunjukkan kapan get() berguna:
# Database siswa dengan informasi opsional
students = {
"Alice": {"age": 20, "major": "CS"},
"Bob": {"age": 19}, # Bob belum menentukan jurusan
"Charlie": {"major": "Math"} # Umur Charlie tidak tercatat
}
# Mengakses informasi yang mungkin hilang secara aman
for name in ["Alice", "Bob", "Charlie"]:
student = students[name]
age = student.get("age", "Unknown")
major = student.get("major", "Undeclared")
print(f"{name}: Age {age}, Major {major}")
# Output:
# Alice: Age 20, Major CS
# Bob: Age 19, Major Undeclared
# Charlie: Age Unknown, Major Math16.1.5) Tipe Key yang Valid
Key dictionary harus dapat di-hash (hashable)—istilah teknis yang berarti nilai key tidak boleh berubah. Dalam praktiknya, ini berarti:
Tipe key yang valid (immutable):
- String:
"name","id_123" - Angka:
42,3.14 - Tuple (jika hanya berisi item immutable):
(1, 2),("x", "y") - Boolean:
True,False None
Tipe key yang tidak valid (mutable):
- List:
[1, 2, 3]tidak bisa menjadi key - Dictionary:
{"a": 1}tidak bisa menjadi key - Set:
{1, 2, 3}tidak bisa menjadi key
# Key yang valid
valid_dict = {
"name": "Alice", # Key string
42: "answer", # Key integer
3.14: "pi", # Key float
(1, 2): "coordinates", # Key tuple
True: "yes", # Key boolean
None: "nothing" # Key None
}
print(valid_dict["name"]) # Output: Alice
print(valid_dict[42]) # Output: answer
print(valid_dict[(1, 2)]) # Output: coordinates
# WARNING: Key tidak valid - hanya untuk demonstrasi
# invalid_dict = {[1, 2]: "list key"} # PROBLEM: TypeError: unhashable type: 'list'
# invalid_dict = {{1, 2}: "set key"} # PROBLEM: TypeError: unhashable type: 'set'Kesalahan Umum Pemula: Kesalahan yang sering terjadi adalah mencoba menggunakan list sebagai key dictionary karena terlihat logis. Misalnya, kamu mungkin ingin menggunakan koordinat [x, y] sebagai key untuk menyimpan data lokasi. Ketika Python memunculkan TypeError: unhashable type: 'list', pemula sering tidak mengerti kenapa—padahal list itu berisi data persis yang ingin mereka gunakan sebagai key.
Alasannya adalah list bersifat mutable (bisa berubah), dan Python membutuhkan key dictionary yang stabil dan tidak bisa berubah. Jika kamu perlu memakai sesuatu yang mirip list sebagai key, ubahlah menjadi tuple terlebih dahulu: tuple([1, 2]) menjadi (1, 2), yang bisa digunakan sebagai key. Tuple bersifat immutable, jadi bekerja dengan sempurna:
# Wrong: mencoba menggunakan list sebagai key
# locations = {[0, 0]: "origin", [1, 0]: "east"} # PROBLEM: TypeError
# Right: konversi ke tuple
locations = {(0, 0): "origin", (1, 0): "east", (0, 1): "north"}
print(locations[(0, 0)]) # Output: origin
print(locations[(1, 0)]) # Output: eastSementara itu, value bisa berupa tipe apa pun—mutable maupun immutable:
# Value bisa berupa tipe apa pun
flexible_dict = {
"numbers": [1, 2, 3], # Value list
"nested": {"a": 1, "b": 2}, # Value dictionary
"function": len, # Value fungsi
"mixed": (1, [2, 3], {"x": 4}) # Tuple yang berisi item mutable
}
print(flexible_dict["numbers"]) # Output: [1, 2, 3]
print(flexible_dict["nested"]["a"]) # Output: 1Kita akan membahas hashability lebih dalam di Bab 17, tetapi untuk saat ini, ingat: gunakan tipe immutable (string, angka, tuple) sebagai key, dan kamu akan baik-baik saja.
16.2) Menambahkan dan Memperbarui Entri Dictionary
16.2.1) Menambahkan Pasangan Key-Value Baru
Menambahkan entri baru ke dictionary itu mudah—cukup tetapkan sebuah value ke key baru:
grades = {"Alice": 95, "Bob": 87}
print(grades) # Output: {'Alice': 95, 'Bob': 87}
# Tambahkan siswa baru
grades["Charlie"] = 92
print(grades) # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92}
# Tambahkan siswa lain
grades["Diana"] = 88
print(grades) # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92, 'Diana': 88}Jika key belum ada, Python akan membuatnya. Jika key sudah ada, Python akan memperbarui value-nya (yang akan kita bahas selanjutnya).
16.2.2) Memperbarui Value yang Sudah Ada
Untuk memperbarui value, cukup tetapkan value baru ke key yang sudah ada:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
print(grades) # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92}
# Perbarui nilai Bob
grades["Bob"] = 90
print(grades) # Output: {'Alice': 95, 'Bob': 90, 'Charlie': 92}
# Perbarui beberapa nilai
grades["Alice"] = 98
grades["Charlie"] = 94
print(grades) # Output: {'Alice': 98, 'Bob': 90, 'Charlie': 94}Python tidak membedakan antara menambahkan dan memperbarui—sintaksnya sama persis. Jika key ada, value diperbarui; jika tidak, entri baru dibuat.
Berikut contoh praktis yang menunjukkan penambahan dan pembaruan:
# Melacak inventaris
inventory = {"apple": 50, "banana": 30}
print("Initial inventory:", inventory) # Output: Initial inventory: {'apple': 50, 'banana': 30}
# Restok apel (memperbarui yang sudah ada)
inventory["apple"] = inventory["apple"] + 20
print("After restocking apples:", inventory) # Output: After restocking apples: {'apple': 70, 'banana': 30}
# Tambah produk baru (menambah key baru)
inventory["orange"] = 40
print("After adding oranges:", inventory) # Output: After adding oranges: {'apple': 70, 'banana': 30, 'orange': 40}
# Menjual beberapa pisang (memperbarui yang sudah ada)
inventory["banana"] = inventory["banana"] - 10
print("After selling bananas:", inventory) # Output: After selling bananas: {'apple': 70, 'banana': 20, 'orange': 40}16.2.3) Menggunakan update() untuk Menggabungkan Dictionary
Metode update() menambahkan beberapa pasangan key-value sekaligus atau menggabungkan dictionary lain ke dictionary saat ini:
grades = {"Alice": 95, "Bob": 87}
print(grades) # Output: {'Alice': 95, 'Bob': 87}
# Tambahkan beberapa siswa sekaligus
new_students = {"Charlie": 92, "Diana": 88}
grades.update(new_students)
print(grades) # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92, 'Diana': 88}
# Perbarui yang sudah ada dan tambahkan yang baru
more_updates = {"Bob": 90, "Eve": 85} # Nilai Bob berubah, Eve baru
grades.update(more_updates)
print(grades) # Output: {'Alice': 95, 'Bob': 90, 'Charlie': 92, 'Diana': 88, 'Eve': 85}Metode update() memodifikasi dictionary secara in place. Jika key sudah ada, value-nya diperbarui; jika tidak, pasangan key-value akan ditambahkan.
Kamu juga bisa memberikan keyword arguments ke update():
student = {"name": "Alice", "age": 20}
print(student) # Output: {'name': 'Alice', 'age': 20}
# Perbarui menggunakan keyword arguments
student.update(age=21, major="Computer Science")
print(student) # Output: {'name': 'Alice', 'age': 21, 'major': 'Computer Science'}Berikut contoh praktis menggabungkan pengaturan konfigurasi:
# Pengaturan default
config = {
"theme": "light",
"font_size": 12,
"auto_save": True
}
# Preferensi pengguna (menimpa beberapa default)
user_prefs = {
"theme": "dark",
"font_size": 14
}
# Gabungkan preferensi pengguna ke config
config.update(user_prefs)
print(config) # Output: {'theme': 'dark', 'font_size': 14, 'auto_save': True}16.2.4) Menggunakan setdefault() untuk Menambah Hanya Jika Key Belum Ada
Metode setdefault() berguna ketika kamu ingin menambahkan pasangan key-value hanya jika key belum ada. Jika key sudah ada, metode ini mengembalikan value saat ini tanpa mengubahnya:
grades = {"Alice": 95, "Bob": 87}
# Tambahkan Charlie (key belum ada)
result = grades.setdefault("Charlie", 90)
print(result) # Output: 90
print(grades) # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 90}
# Coba tambahkan Alice (key sudah ada - tidak berubah)
result = grades.setdefault("Alice", 80)
print(result) # Output: 95 (existing value returned)
print(grades) # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 90} (unchanged)Ini sangat berguna ketika kamu ingin memastikan semua key konfigurasi yang diperlukan ada dengan value default, sambil tetap mempertahankan value yang sudah dikustomisasi pengguna:
# Konfigurasi aplikasi dengan default
config = {"theme": "light", "font_size": 12}
# Pastikan semua pengaturan yang diperlukan ada dengan default
config.setdefault("auto_save", True)
config.setdefault("language", "en")
config.setdefault("theme", "dark") # Tidak akan berubah - sudah ada
print(config)
# Output: {'theme': 'light', 'font_size': 12, 'auto_save': True, 'language': 'en'}
# Sekarang akses semua pengaturan dengan aman
print(f"Theme: {config['theme']}") # Output: Theme: light
print(f"Auto-save: {config['auto_save']}") # Output: Auto-save: True
print(f"Language: {config['language']}") # Output: Language: en16.3) Menghapus Entri Dictionary dengan del dan pop()
16.3.1) Menghapus Entri dengan del
Statement del menghapus pasangan key-value dari dictionary:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
print(grades) # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92, 'Diana': 88}
# Hapus Charlie
del grades["Charlie"]
print(grades) # Output: {'Alice': 95, 'Bob': 87, 'Diana': 88}
# Hapus siswa lain
del grades["Bob"]
print(grades) # Output: {'Alice': 95, 'Diana': 88}Jika kamu mencoba menghapus key yang tidak ada, Python akan memunculkan KeyError:
grades = {"Alice": 95, "Bob": 87}
# WARNING: KeyError - for demonstration only
# del grades["Charlie"] # PROBLEM: KeyError: 'Charlie'Untuk menghapus key dengan aman yang mungkin tidak ada, cek dulu:
grades = {"Alice": 95, "Bob": 87}
# Penghapusan aman
if "Charlie" in grades:
del grades["Charlie"]
else:
print("Charlie tidak ditemukan") # Output: Charlie tidak ditemukan16.3.2) Menghapus dan Mengambil dengan pop()
Metode pop() menghapus sebuah key dan mengembalikan value-nya. Ini berguna ketika kamu perlu menghapus sebuah entri sekaligus menggunakan value-nya:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
print(grades) # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92}
# Hapus dan ambil nilai Bob
bob_grade = grades.pop("Bob")
print(bob_grade) # Output: 87
print(grades) # Output: {'Alice': 95, 'Charlie': 92}
# Hapus dan gunakan value-nya
charlie_grade = grades.pop("Charlie")
print(f"Charlie's final grade was {charlie_grade}") # Output: Charlie's final grade was 92
print(grades) # Output: {'Alice': 95}Seperti del, pop() memunculkan KeyError jika key tidak ada. Namun, kamu bisa memberikan nilai default untuk dikembalikan:
grades = {"Alice": 95, "Bob": 87}
# Pop dengan nilai default (key tidak ada)
diana_grade = grades.pop("Diana", 0)
print(diana_grade) # Output: 0
print(grades) # Output: {'Alice': 95, 'Bob': 87} (unchanged)
# Pop dengan nilai default (key ada)
alice_grade = grades.pop("Alice", 0)
print(alice_grade) # Output: 95
print(grades) # Output: {'Bob': 87}16.3.3) Menghapus Semua Entri dengan clear()
Metode clear() menghapus semua pasangan key-value dari dictionary, sehingga dictionary menjadi kosong:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
print(grades) # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92}
# Bersihkan semua entri
grades.clear()
print(grades) # Output: {}
print(len(grades)) # Output: 0Ini lebih eksplisit daripada menetapkan ulang ke dictionary kosong (grades = {}), terutama ketika variabel lain mereferensikan dictionary yang sama:
# Demonstrasikan perbedaannya
grades = {"Alice": 95, "Bob": 87}
backup = grades # backup mereferensikan dictionary yang sama
# Menggunakan clear() - memengaruhi kedua variabel
grades.clear()
print(grades) # Output: {}
print(backup) # Output: {} (same dictionary was cleared)
# Reset untuk contoh berikutnya
grades = {"Alice": 95, "Bob": 87}
backup = grades
# Menetapkan ulang - hanya memengaruhi grades
grades = {}
print(grades) # Output: {}
print(backup) # Output: {'Alice': 95, 'Bob': 87} (different dictionary now)Kita akan membahas perilaku ini lebih jauh di Bab 18 ketika membahas reference semantics, tetapi untuk saat ini, ingat: clear() mengosongkan dictionary yang ada, sedangkan penetapan ulang membuat dictionary kosong yang baru.
16.4) Objek Tampilan Dictionary: keys(), values(), dan items()
16.4.1) Memahami View Dictionary
Dictionary menyediakan tiga metode yang mengembalikan objek tampilan (view object)—objek khusus yang memberikan tampilan dinamis dari key, value, atau pasangan key-value milik dictionary. View ini secara otomatis mencerminkan perubahan pada dictionary:
keys(): Mengembalikan view dari semua keyvalues(): Mengembalikan view dari semua valueitems(): Mengembalikan view dari semua pasangan key-value (sebagai tuple)
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
# Ambil view
keys_view = grades.keys()
values_view = grades.values()
items_view = grades.items()
print(keys_view) # Output: dict_keys(['Alice', 'Bob', 'Charlie'])
print(values_view) # Output: dict_values([95, 87, 92])
print(items_view) # Output: dict_items([('Alice', 95), ('Bob', 87), ('Charlie', 92)])Ini bukan list—ini adalah objek view. Namun, kamu bisa mengonversinya ke list jika diperlukan:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
# Konversi view menjadi list
keys_list = list(grades.keys())
values_list = list(grades.values())
items_list = list(grades.items())
print(keys_list) # Output: ['Alice', 'Bob', 'Charlie']
print(values_list) # Output: [95, 87, 92]
print(items_list) # Output: [('Alice', 95), ('Bob', 87), ('Charlie', 92)]16.4.2) View Bersifat Dinamis
Objek view secara otomatis mencerminkan perubahan pada dictionary:
grades = {"Alice": 95, "Bob": 87}
# Buat sebuah view
keys_view = grades.keys()
print(keys_view) # Output: dict_keys(['Alice', 'Bob'])
# Ubah dictionary
grades["Charlie"] = 92
print(keys_view) # Output: dict_keys(['Alice', 'Bob', 'Charlie'])
# Hapus sebuah entri
del grades["Bob"]
print(keys_view) # Output: dict_keys(['Alice', 'Charlie'])Perilaku dinamis ini berguna ketika kamu perlu bekerja dengan isi dictionary yang mungkin berubah. Namun, jika kamu membutuhkan snapshot yang tidak akan berubah, konversikan view menjadi list:
grades = {"Alice": 95, "Bob": 87}
# Buat sebuah snapshot
keys_snapshot = list(grades.keys())
print(keys_snapshot) # Output: ['Alice', 'Bob']
# Ubah dictionary
grades["Charlie"] = 92
print(keys_snapshot) # Output: ['Alice', 'Bob'] (unchanged)16.4.3) Bekerja dengan keys()
Metode keys() mengembalikan view dari semua key dictionary. Ini berguna untuk mengecek key apa saja yang ada atau melakukan iterasi atas key tersebut:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
# Ambil semua key
keys = grades.keys()
print(keys) # Output: dict_keys(['Alice', 'Bob', 'Charlie'])
# Cek apakah sebuah key ada
if "Alice" in keys:
print("Alice ada di buku nilai") # Output: Alice ada di buku nilai
# Hitung jumlah siswa
print(f"Number of students: {len(keys)}") # Output: Number of students: 3Kamu juga bisa mengecek membership langsung pada dictionary tanpa memanggil keys():
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
# Ini setara
if "Alice" in grades.keys():
print("Found (using keys())")
if "Alice" in grades:
print("Found (direct check)") # Ini lebih umum dan ringkas
# Output:
# Found (using keys())
# Found (direct check)16.4.4) Bekerja dengan values()
Metode values() mengembalikan view dari semua value dictionary. Ini berguna ketika kamu perlu memproses value tanpa peduli key-nya:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
# Ambil semua value
values = grades.values()
print(values) # Output: dict_values([95, 87, 92, 88])
# Hitung statistik
total = sum(values)
count = len(values)
average = total / count
print(f"Total points: {total}") # Output: Total points: 362
print(f"Number of students: {count}") # Output: Number of students: 4
print(f"Average grade: {average}") # Output: Average grade: 90.5
# Temukan nilai tertinggi dan terendah
print(f"Highest grade: {max(values)}") # Output: Highest grade: 95
print(f"Lowest grade: {min(values)}") # Output: Lowest grade: 8716.4.5) Bekerja dengan items()
Metode items() mengembalikan view dari pasangan key-value sebagai tuple. Ini adalah view yang paling sering digunakan karena memberi kamu key dan value sekaligus:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
# Ambil semua pasangan key-value
items = grades.items()
print(items) # Output: dict_items([('Alice', 95), ('Bob', 87), ('Charlie', 92)])
# Konversi ke list agar tuple terlihat jelas
items_list = list(items)
print(items_list) # Output: [('Alice', 95), ('Bob', 87), ('Charlie', 92)]
# Akses tuple satu per satu
first_item = items_list[0]
print(first_item) # Output: ('Alice', 95)
print(first_item[0]) # Output: Alice
print(first_item[1]) # Output: 95View items() sangat berguna untuk iterasi, yang akan kita bahas secara detail di bagian berikutnya. Berikut pratinjaunya:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
# Proses setiap pasangan key-value
for name, grade in grades.items():
print(f"{name}: {grade}")
# Output:
# Alice: 95
# Bob: 87
# Charlie: 9216.5) Iterasi atas Key, Value, dan Item
16.5.1) Iterasi atas Key (Perilaku Default)
Ketika kamu melakukan iterasi atas dictionary secara langsung dengan loop for, kamu melakukan iterasi atas key-nya:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
# Iterasi atas key (implisit)
for name in grades:
print(name)
# Output:
# Alice
# Bob
# CharlieIni setara dengan melakukan iterasi atas grades.keys():
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
# Iterasi atas key (eksplisit)
for name in grades.keys():
print(name)
# Output:
# Alice
# Bob
# CharlieKedua pendekatan bekerja sama persis. Versi implisit (tanpa .keys()) lebih umum dan ringkas.
Berikut contoh praktis menggunakan key untuk mengakses value:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
# Temukan siswa yang lulus (grade >= 90)
passing_students = []
for name in grades:
if grades[name] >= 90:
passing_students.append(name)
print("Students who passed:", passing_students) # Output: Students who passed: ['Alice', 'Charlie']16.5.2) Iterasi atas Value
Untuk melakukan iterasi hanya pada value, gunakan values():
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
# Iterasi atas value
for grade in grades.values():
print(grade)
# Output:
# 95
# 87
# 92
# 88Ini berguna ketika kamu perlu memproses value tetapi tidak peduli key mana yang terasosiasi:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
# Hitung total dan rata-rata
total = 0
count = 0
for grade in grades.values():
total = total + grade
count = count + 1
average = total / count
print(f"Class average: {average}") # Output: Class average: 90.5
# Cek apakah semua siswa lulus
all_passed = True
for grade in grades.values():
if grade < 60:
all_passed = False
break
if all_passed:
print("All students passed!") # Output: All students passed!16.5.3) Iterasi atas Pasangan Key-Value dengan items()
Pola iterasi yang paling umum dan berguna adalah menggunakan items() untuk mendapatkan key dan value:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
# Iterasi atas pasangan key-value
for name, grade in grades.items():
print(f"{name} scored {grade}")
# Output:
# Alice scored 95
# Bob scored 87
# Charlie scored 92Perhatikan unpacking tuple: for name, grade in grades.items(). Setiap item adalah tuple seperti ("Alice", 95), dan kita membukanya menjadi dua variabel. Ini jauh lebih mudah dibaca daripada mengakses indeks tuple:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
# Tanpa unpacking (kurang mudah dibaca)
for item in grades.items():
print(f"{item[0]} scored {item[1]}")
# Dengan unpacking (lebih mudah dibaca)
for name, grade in grades.items():
print(f"{name} scored {grade}")
# Both produce the same output:
# Alice scored 95
# Bob scored 87
# Charlie scored 9216.5.4) Memodifikasi Dictionary Saat Iterasi
Peringatan: Mengubah ukuran dictionary (menambah atau menghapus key) saat melakukan iterasi bisa menyebabkan error atau perilaku yang tidak terduga:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
# WARNING: RuntimeError - for demonstration only
# for name in grades:
# if grades[name] < 90:
# del grades[name] # PROBLEM: RuntimeError: dictionary changed size during iterationDi Python modern (3.7+), ini langsung memunculkan RuntimeError begitu kamu mencoba mengubah ukuran dictionary. Python mendeteksi modifikasi tersebut dan menghentikan eksekusi untuk mencegah perilaku yang tidak dapat diprediksi.
Di versi Python yang lebih lama, ini bisa membuat iterator:
- Melewati item yang seharusnya diproses
- Memproses item yang sama dua kali
- Menghasilkan hasil yang tidak konsisten
Inilah alasan Python sekarang gagal cepat dengan pesan error yang jelas.
Jika kamu perlu memodifikasi dictionary selama iterasi, lakukan iterasi atas salinan key:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
# Aman: iterasi atas salinan key
for name in list(grades.keys()):
if grades[name] < 90:
del grades[name]
print(grades) # Output: {'Alice': 95, 'Charlie': 92}Atau buat dictionary baru yang hanya berisi entri yang kamu inginkan:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
# Bangun dictionary baru dengan entri yang difilter
high_grades = {}
for name, grade in grades.items():
if grade >= 90:
high_grades[name] = grade
print(high_grades) # Output: {'Alice': 95, 'Charlie': 92}Pendekatan kedua sering kali lebih jelas dan aman. Kita akan belajar cara yang lebih elegan lagi untuk melakukan ini dengan dictionary comprehensions di Bab 35.
16.6) Metode Dictionary yang Umum
16.6.1) Mengecek Key dengan in dan not in
Operator in dan not in mengecek apakah sebuah key ada di dalam dictionary:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
# Cek apakah key ada
if "Alice" in grades:
print("Alice ada di buku nilai") # Output: Alice ada di buku nilai
if "David" not in grades:
print("David tidak ada di buku nilai") # Output: David tidak ada di buku nilaiIni adalah cara yang disarankan untuk mengecek keberadaan key sebelum mengakses value. Ini lebih mudah dibaca dan lebih Pythonic daripada menggunakan get() lalu mengecek None:
grades = {"Alice": 95, "Bob": 87}
# Disarankan: menggunakan in
if "Alice" in grades:
print(f"Alice's grade: {grades['Alice']}") # Output: Alice's grade: 95
# Alternatif: menggunakan get() dan mengecek None
if grades.get("Alice") is not None:
print(f"Alice's grade: {grades['Alice']}") # Output: Alice's grade: 9516.6.2) Mendapatkan Jumlah Entri dengan len()
Fungsi len() mengembalikan jumlah pasangan key-value di dalam dictionary:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
print(len(grades)) # Output: 3
# Dictionary kosong
empty = {}
print(len(empty)) # Output: 0
# Setelah modifikasi
grades["Diana"] = 88
print(len(grades)) # Output: 4
del grades["Bob"]
print(len(grades)) # Output: 3Ini berguna untuk mengecek apakah dictionary kosong atau untuk melaporkan statistik:
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
if len(grades) == 0:
print("Tidak ada siswa di buku nilai")
else:
total = sum(grades.values())
average = total / len(grades)
print(f"{len(grades)} students, average grade: {average}")
# Output: 4 siswa, rata-rata nilai: 90.516.6.3) Menyalin Dictionary dengan copy()
Metode copy() membuat salinan dangkal (shallow copy) dari dictionary—sebuah dictionary baru dengan pasangan key-value yang sama:
original = {"Alice": 95, "Bob": 87}
duplicate = original.copy()
print(original) # Output: {'Alice': 95, 'Bob': 87}
print(duplicate) # Output: {'Alice': 95, 'Bob': 87}
# Ubah salinannya
duplicate["Charlie"] = 92
print(original) # Output: {'Alice': 95, 'Bob': 87} (unchanged)
print(duplicate) # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92}Ini berbeda dari assignment biasa, yang membuat referensi ke dictionary yang sama:
original = {"Alice": 95, "Bob": 87}
reference = original # Bukan salinan - dictionary yang sama
# Modifikasi melalui reference
reference["Charlie"] = 92
print(original) # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92} (changed!)
print(reference) # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92}Kita akan membahas shallow vs deep copy secara detail di Bab 18. Untuk saat ini, ingat: gunakan copy() ketika kamu menginginkan duplikat dictionary yang independen.
16.6.4) Menggabungkan Dictionary dengan Operator | (Python 3.9+)
Python 3.9 memperkenalkan operator | untuk menggabungkan dictionary. Operator | membuat dictionary baru yang menggabungkan semua key dari kedua dictionary. Untuk key duplikat, value di sisi kanan akan menimpa value di sisi kiri. Kedua dictionary asli tetap tidak berubah.
defaults = {"theme": "light", "font_size": 12, "auto_save": True}
user_prefs = {"theme": "dark", "font_size": 14}
# Gabungkan dictionary (user_prefs menimpa defaults)
config = defaults | user_prefs
print(config) # Output: {'theme': 'dark', 'font_size': 14, 'auto_save': True}
# Dictionary asli tidak berubah
print(defaults) # Output: {'theme': 'light', 'font_size': 12, 'auto_save': True}
print(user_prefs) # Output: {'theme': 'dark', 'font_size': 14}Berikut contoh lain yang menunjukkan bagaimana ini berguna untuk menggabungkan data dari beberapa sumber:
# Informasi produk dari dua pemasok
supplier_a = {
"laptop": {"price": 999.99, "stock": 15},
"mouse": {"price": 29.99, "stock": 50}
}
supplier_b = {
"laptop": {"price": 949.99, "stock": 20}, # Harga dan stok lebih baik
"keyboard": {"price": 79.99, "stock": 30}
}
# Gabungkan: data supplier_b menimpa supplier_a untuk produk yang sama
combined = supplier_a | supplier_b
print(combined)
# Output: {'laptop': {'price': 949.99, 'stock': 20}, 'mouse': {'price': 29.99, 'stock': 50}, 'keyboard': {'price': 79.99, 'stock': 30}}
# Sekarang kita punya laptop dari supplier_b (penawaran lebih baik), mouse dari supplier_a, dan keyboard dari supplier_bOperator |= menggabungkan in place (memodifikasi dictionary kiri):
config = {"theme": "light", "font_size": 12, "auto_save": True}
user_prefs = {"theme": "dark", "font_size": 14}
# Gabungkan in place
config |= user_prefs
print(config) # Output: {'theme': 'dark', 'font_size': 14, 'auto_save': True}Ini setara dengan menggunakan update() tetapi lebih ringkas:
config = {"theme": "light", "font_size": 12}
user_prefs = {"theme": "dark", "font_size": 14}
# Ini setara
config.update(user_prefs)
# config |= user_prefs
print(config) # Output: {'theme': 'dark', 'font_size': 14}16.7) Dictionary Bersarang untuk Data Terstruktur
16.7.1) Membuat Dictionary Bersarang
Kenapa memakai dictionary bersarang? Bayangkan melacak informasi siswa. Kamu bisa membuat dictionary terpisah: ages = {"Alice": 20, "Bob": 19}, majors = {"Alice": "CS", "Bob": "Math"}, gpas = {"Alice": 3.8, "Bob": 3.6}. Tapi ini menjadi merepotkan—kamu harus menjaga tiga dictionary tetap sinkron, dan mencari semua informasi untuk satu siswa membutuhkan tiga kali lookup terpisah. Dictionary bersarang menyelesaikan ini dengan mengelompokkan data terkait bersama: satu nama siswa memetakan ke semua informasi mereka dalam satu kali lookup.
Sebuah dictionary bersarang (nested dictionary) adalah dictionary yang berisi dictionary lain sebagai value. Ini berguna untuk merepresentasikan data terstruktur dan hierarkis:
# Catatan siswa dengan beberapa atribut
students = {
"Alice": {
"age": 20,
"major": "Computer Science",
"gpa": 3.8
},
"Bob": {
"age": 19,
"major": "Mathematics",
"gpa": 3.6
},
"Charlie": {
"age": 21,
"major": "Physics",
"gpa": 3.9
}
}
print(students)
# Output: {'Alice': {'age': 20, 'major': 'Computer Science', 'gpa': 3.8}, 'Bob': {'age': 19, 'major': 'Mathematics', 'gpa': 3.6}, 'Charlie': {'age': 21, 'major': 'Physics', 'gpa': 3.9}}Setiap nama siswa memetakan ke dictionary lain yang berisi atribut-atribut mereka. Struktur ini jauh lebih fleksibel dan mudah dirawat daripada menggunakan dictionary terpisah untuk setiap atribut.
16.7.2) Mengakses Nilai Bersarang
Untuk mengakses nilai bersarang, gunakan beberapa kurung siku:
students = {
"Alice": {"age": 20, "major": "Computer Science", "gpa": 3.8},
"Bob": {"age": 19, "major": "Mathematics", "gpa": 3.6}
}
# Akses nilai bersarang
alice_age = students["Alice"]["age"]
print(alice_age) # Output: 20
bob_major = students["Bob"]["major"]
print(bob_major) # Output: Mathematics
# Gunakan dalam ekspresi
print(f"Alice is {students['Alice']['age']} years old")
# Output: Alice is 20 years old
print(f"Bob's GPA: {students['Bob']['gpa']}")
# Output: Bob's GPA: 3.6Setiap kurung mengakses satu level nesting. Pertama students["Alice"] mengambil dictionary bagian dalam, lalu ["age"] mengambil nilai umur dari dictionary tersebut.
16.7.3) Mengakses Nilai Bersarang dengan Aman
Saat mengakses dictionary bersarang, kamu perlu mengecek bahwa tiap level ada:
students = {
"Alice": {"age": 20, "major": "Computer Science"},
"Bob": {"age": 19} # Bob belum menentukan jurusan
}
# Akses tidak aman - mungkin memunculkan KeyError
# print(students["Bob"]["major"]) # PROBLEM: KeyError: 'major'
# Akses aman dengan beberapa pengecekan
if "Bob" in students:
if "major" in students["Bob"]:
print(f"Bob's major: {students['Bob']['major']}")
else:
print("Bob belum menentukan jurusan") # Output: Bob hasn't declared a major
# Menggunakan get() untuk akses bersarang yang aman
bob_major = students.get("Bob", {}).get("major", "Undeclared")
print(f"Bob's major: {bob_major}") # Output: Bob's major: UndeclaredRantai get() bekerja karena jika "Bob" tidak ada, get() mengembalikan dictionary kosong {}, lalu get() kedua dengan aman mengembalikan "Undeclared".
16.7.4) Memodifikasi Dictionary Bersarang
Kamu bisa menambahkan, memperbarui, atau menghapus entri di dictionary bersarang:
students = {
"Alice": {"age": 20, "major": "Computer Science", "gpa": 3.8},
"Bob": {"age": 19, "major": "Mathematics", "gpa": 3.6}
}
# Perbarui nilai bersarang
students["Alice"]["gpa"] = 3.9
print(f"Alice's new GPA: {students['Alice']['gpa']}") # Output: Alice's new GPA: 3.9
# Tambahkan atribut baru ke siswa yang sudah ada
students["Bob"]["email"] = "bob@university.edu"
print(students["Bob"])
# Output: {'age': 19, 'major': 'Mathematics', 'gpa': 3.6, 'email': 'bob@university.edu'}
# Tambahkan siswa baru dengan data bersarang
students["Charlie"] = {
"age": 21,
"major": "Physics",
"gpa": 3.7
}
print(f"Number of students: {len(students)}") # Output: Number of students: 3
# Hapus sebuah atribut
del students["Bob"]["email"]
print(students["Bob"])
# Output: {'age': 19, 'major': 'Mathematics', 'gpa': 3.6}16.7.5) Iterasi atas Dictionary Bersarang
Kamu bisa melakukan iterasi atas dictionary bersarang menggunakan loop bersarang:
students = {
"Alice": {"age": 20, "major": "Computer Science", "gpa": 3.8},
"Bob": {"age": 19, "major": "Mathematics", "gpa": 3.6},
"Charlie": {"age": 21, "major": "Physics", "gpa": 3.9}
}
# Iterasi atas siswa dan atributnya
for name, info in students.items():
print(f"\n{name}:")
for key, value in info.items():
print(f" {key}: {value}")
# Output:
# Alice:
# age: 20
# major: Computer Science
# gpa: 3.8
#
# Bob:
# age: 19
# major: Mathematics
# gpa: 3.6
#
# Charlie:
# age: 21
# major: Physics
# gpa: 3.9Berikut contoh praktis menemukan siswa yang memenuhi kriteria tertentu:
students = {
"Alice": {"age": 20, "major": "Computer Science", "gpa": 3.8},
"Bob": {"age": 19, "major": "Mathematics", "gpa": 3.6},
"Charlie": {"age": 21, "major": "Physics", "gpa": 3.9},
"Diana": {"age": 20, "major": "Computer Science", "gpa": 3.5}
}
# Temukan siswa CS dengan GPA di atas 3.7
print("High-performing CS students:")
for name, info in students.items():
if info["major"] == "Computer Science" and info["gpa"] >= 3.7:
print(f" {name} (GPA: {info['gpa']})")
# Output:
# High-performing CS students:
# Alice (GPA: 3.8)Dictionary adalah salah satu struktur data Python yang paling kuat dan serbaguna. Dictionary menyediakan lookup cepat, pengorganisasian yang fleksibel, dan solusi yang elegan untuk masalah pemrograman yang umum. Saat kamu terus belajar Python, kamu akan menemukan dictionary muncul di mana-mana—mulai dari pengaturan konfigurasi hingga pemrosesan data hingga membangun aplikasi yang kompleks.
Pola-pola yang kita bahas di bab ini—counting, grouping, lookup table, dan transformasi data—menjadi fondasi untuk bekerja dengan data terstruktur di Python. Di bab berikutnya, kita akan mengeksplorasi set, tipe koleksi lain yang melengkapi dictionary untuk bekerja dengan data unik dan tidak berurutan.