Bab 9 — Struktur Data Bawaan: Wadah untuk Data Pohon, Ikan, dan Ternak
Seri B2 — Fondasi Bahasa Python
Semua skrip bab ini ada di folder kode/bab09/. Di versi web, Anda juga bisa mengunduh semuanya sekaligus (zip).
Sampai Bab 8, setiap nilai kita simpan dalam satu variabel: bobot_g = 520. Tetapi data lapangan jumlahnya banyak: ratusan pohon, puluhan kolam. Membuat ratusan variabel jelas tidak mungkin. Python menyediakan struktur data: wadah yang menampung banyak nilai sekaligus. Bayangkan lemari arsip dengan empat jenis laci yang berbeda.
| Wadah | Bentuk | Bisa diubah? | Cocok untuk |
|---|---|---|---|
| list | [800, 1250, 640] |
ya | daftar berurutan: jumlah ikan tiap kolam |
| tuple | (-6.6, 106.8) |
tidak | data tetap: koordinat |
| dict | {"jenis": "Jati"} |
ya | data berlabel: satu pohon |
| set | {"lele", "nila"} |
ya | kumpulan tanpa duplikat: jenis ikan |
list: daftar yang bisa diubah
01_list.py
# Bab 9 - list: daftar yang bisa diubah
ikan_per_kolam = [800, 1250, 640]
print(ikan_per_kolam)
print("Kolam pertama:", ikan_per_kolam[0]) # nomor urut mulai dari 0
print("Kolam terakhir:", ikan_per_kolam[-1]) # -1 = yang paling belakang
print("Jumlah kolam:", len(ikan_per_kolam))
print("Total ikan:", sum(ikan_per_kolam))
print("Kolam terpadat:", max(ikan_per_kolam))[800, 1250, 640]
Kolam pertama: 800
Kolam terakhir: 640
Jumlah kolam: 3
Total ikan: 2690
Kolam terpadat: 1250
Tiga hal penting:
- List ditulis dalam kurung siku
[ ], isinya dipisah koma. - Nomor urut (indeks) mulai dari 0: isi pertama di
[0]. Nomor negatif menghitung dari belakang:[-1]adalah yang terakhir. - Fungsi bawaan yang berguna:
len()(banyaknya),sum()(jumlah),max()(terbesar),min()(terkecil).
Isi list bisa diubah setelah dibuat:
02_list_ubah.py
# Bab 9 - Mengubah isi list
ikan_per_kolam = [800, 1250, 640]
ikan_per_kolam.append(900) # tambah di belakang
ikan_per_kolam[0] = 820 # ganti isi nomor 0
ikan_per_kolam.remove(640) # buang nilai 640
print(ikan_per_kolam)
print(1250 in ikan_per_kolam) # apakah ada?
print(500 in ikan_per_kolam)
ikan_per_kolam.sort() # urutkan dari kecil
print(ikan_per_kolam)[820, 1250, 900]
True
False
[820, 900, 1250]
append(x)menambah di belakang;remove(x)membuang nilai pertama yang cocok.daftar[0] = 820mengganti isi nomor 0.x in daftarmenjawabTrueatauFalse: ada tidaknya nilai itu.sort()mengurutkan list di tempat (list aslinya berubah).
Slicing: mengambil potongan
Rumusnya daftar[mulai:berhenti:langkah]. Seperti range(), angka berhenti tidak ikut.

[1:4] mengambil nomor 1, 2, 3.03_slicing.py
# Bab 9 - Slicing: mengambil potongan list [mulai:berhenti:langkah]
bobot_g = [480, 500, 510, 520, 530, 540]
print(bobot_g[1:4]) # nomor 1 sampai 3 (4 tidak ikut)
print(bobot_g[:3]) # tiga pertama
print(bobot_g[3:]) # dari nomor 3 sampai habis
print(bobot_g[::2]) # loncat 2
print(bobot_g[::-1]) # dibalik[500, 510, 520]
[480, 500, 510]
[520, 530, 540]
[480, 510, 530]
[540, 530, 520, 510, 500, 480]
Bagian yang dikosongkan berarti “dari awal” atau “sampai akhir”. Trik [::-1] membalik seluruh urutan.
tuple: daftar yang dikunci
Tuple mirip list, tetapi ditulis dengan kurung biasa dan tidak bisa diubah setelah dibuat. Cocok untuk data yang memang tidak boleh berubah, seperti koordinat lokasi.
04_tuple.py
# Bab 9 - tuple: daftar yang tidak boleh diubah (cocok untuk koordinat)
lokasi_kolam = (-6.6, 106.8) # (lintang, bujur): angka contoh
lintang, bujur = lokasi_kolam # membongkar isi tuple
print(f"Lintang: {lintang}")
print(f"Bujur: {bujur}")
print(lokasi_kolam[0])Lintang: -6.6
Bujur: 106.8
-6.6
Baris lintang, bujur = lokasi_kolam disebut unpacking: membongkar isi tuple ke dalam beberapa variabel sekaligus. Mencoba mengubah isinya akan gagal:
08_tuple_salah.py
# Bab 9 - Salah: mencoba mengubah isi tuple
lokasi_kolam = (-6.6, 106.8)
lokasi_kolam[0] = -6.7Traceback (most recent call last):
File "08_tuple_salah.py", line 3, in <module>
lokasi_kolam[0] = -6.7
~~~~~~~~~~~~^^^
TypeError: 'tuple' object does not support item assignment
Pesannya jelas: “objek tuple tidak mendukung penugasan item”. Itu justru fungsi tuple: melindungi data dari perubahan tak sengaja.
dict: data berlabel
Bila list diakses dengan nomor, dict diakses dengan label (disebut kunci). Sempurna untuk menggambarkan satu pohon:
05_dict.py
# Bab 9 - dict: data berlabel (kunci -> nilai)
pohon = {"jenis": "Jati", "diameter_cm": 32.5, "tinggi_m": 18}
print(pohon["jenis"])
pohon["tinggi_m"] = 19 # ubah nilai
pohon["sehat"] = True # tambah label baru
print(pohon)
print(pohon.get("warna", "belum dicatat")) # aman bila label tidak ada
for label, isi in pohon.items():
print(f"{label}: {isi}")Jati
{'jenis': 'Jati', 'diameter_cm': 32.5, 'tinggi_m': 19, 'sehat': True}
belum dicatat
jenis: Jati
diameter_cm: 32.5
tinggi_m: 19
sehat: True
- Ditulis dalam kurung kurawal
{ }, tiap isi berpasangan"kunci": nilai. pohon["jenis"]mengambil nilainya;pohon["sehat"] = Truemenambah atau mengubah..get("warna", "belum dicatat")aman: bila label tidak ada, ia mengembalikan nilai cadangan..items()memberi pasangan label dan isi untuk dipakai difor.
Bila label tidak ada dan Anda memakai kurung siku, Python protes:
09_label_tak_ada.py
# Bab 9 - Salah: meminta label yang tidak ada di dict
pohon = {"jenis": "Jati", "diameter_cm": 32.5}
print(pohon["warna"])Traceback (most recent call last):
File "09_label_tak_ada.py", line 3, in <module>
print(pohon["warna"])
~~~~~^^^^^^^^^
KeyError: 'warna'
KeyError berarti “kunci tidak ditemukan”, dan Python menyebut nama kunci yang gagal.
set: kumpulan tanpa duplikat
Set otomatis membuang duplikat dan tidak punya urutan. Berguna untuk pertanyaan seperti “jenis ikan apa saja yang ada?”
06_set.py
# Bab 9 - set: kumpulan tanpa duplikat dan tanpa urutan
ikan_kolam_a = {"lele", "nila", "gurami", "lele"}
ikan_kolam_b = {"nila", "patin"}
print("Banyak jenis di kolam A:", len(ikan_kolam_a)) # lele hanya dihitung sekali
print(sorted(ikan_kolam_a))
print("Ada nila di kolam A?", "nila" in ikan_kolam_a)
print("Ada di kedua kolam:", sorted(ikan_kolam_a & ikan_kolam_b))
print("Ada di salah satu:", sorted(ikan_kolam_a | ikan_kolam_b))Banyak jenis di kolam A: 3
['gurami', 'lele', 'nila']
Ada nila di kolam A? True
Ada di kedua kolam: ['nila']
Ada di salah satu: ['gurami', 'lele', 'nila', 'patin']
"lele" ditulis dua kali tetapi hanya dihitung sekali. Operator & memberi irisan (ada di kedua kolam) dan | memberi gabungan. Kita memakai sorted() supaya tampilannya berurutan, karena set sendiri tidak menjamin urutan.
Comprehension: list baru dalam satu baris
07_comprehension.py
# Bab 9 - Comprehension: membuat list baru dalam satu baris
bobot_g = [520, 480, 560, 495]
bobot_kg = [g / 1000 for g in bobot_g]
siap_panen = [g for g in bobot_g if g >= 500]
print(bobot_kg)
print(siap_panen)[0.52, 0.48, 0.56, 0.495]
[520, 560]
Baca [g / 1000 for g in bobot_g] seperti kalimat: “untuk setiap g di bobot_g, hitung g / 1000.” Menambahkan if di belakang menyaring: [g for g in bobot_g if g >= 500] hanya mengambil yang ≥ 500.
Comprehension itu singkatan dari perulangan for yang mengisi list. Kalau terasa membingungkan, tulis dulu dengan for biasa. Setelah paham, baru dipadatkan.
Proyek Bersambung B2: data pohon
Sekarang gabungkan: list berisi dict. Tiap pohon adalah satu dict, dan kebunnya adalah list dari dict-dict itu.
10_proyek_data_pohon.py
# Bab 9 - Proyek bersambung B2: data pohon dalam list berisi dict
data_pohon = [
{"jenis": "Jati", "diameter_cm": 32.5, "tinggi_m": 18, "sehat": True},
{"jenis": "Meranti", "diameter_cm": 45.2, "tinggi_m": 27, "sehat": True},
{"jenis": "Mahoni", "diameter_cm": 28.0, "tinggi_m": 15, "sehat": False},
]
for pohon in data_pohon:
status = "sehat" if pohon["sehat"] else "perlu diperiksa"
print(f"{pohon['jenis']:8} diameter {pohon['diameter_cm']:5.1f} cm, {status}")
diameter = [pohon["diameter_cm"] for pohon in data_pohon]
print(f"Rata-rata diameter: {sum(diameter) / len(diameter):.2f} cm")
sehat_saja = [pohon["jenis"] for pohon in data_pohon if pohon["sehat"]]
print("Pohon sehat:", sehat_saja)Jati diameter 32.5 cm, sehat
Meranti diameter 45.2 cm, sehat
Mahoni diameter 28.0 cm, perlu diperiksa
Rata-rata diameter: 35.23 cm
Pohon sehat: ['Jati', 'Meranti']
Beberapa hal baru di baris print:
{pohon['jenis']:8}berarti “tampilkan dengan lebar 8 karakter”, supaya kolomnya rata. Tanda kutip tunggal dipakai di dalamnya karena f-string-nya sudah dibungkus kutip ganda.{pohon['diameter_cm']:5.1f}berarti lebar 5, satu angka di belakang titik."sehat" if pohon["sehat"] else "perlu diperiksa"adalahifsatu baris: nilainya"sehat"bila benar, kalau tidak yang satunya.
Rata-rata diameter: (32,5 + 45,2 + 28,0) ÷ 3 = 35,23 cm. Pohon Mahoni tidak sehat, jadi tidak masuk daftar “Pohon sehat”.
Latihan
- Buat list berisi bobot lima ekor sapi (angka bebas). Cetak bobot terberat, bobot teringan, dan rata-ratanya.
- Dari list
[480, 500, 510, 520, 530, 540], ambil dengan slicing: tiga terakhir, dan tiga angka pertama dibalik. - Buat dict untuk satu kolam dengan label
nama,jumlah_ikan,bobot_rata_g, dansiap_panen(hasil perbandingan). Cetak semua isinya denganfordan.items(). - Tantangan: tambahkan satu pohon lagi ke
10_proyek_data_pohon.py, lalu buat list comprehension berisi jenis pohon yang tingginya lebih dari 20 m.
Ringkasan Bab
- list
[...]: berurutan, bisa diubah; indeks mulai dari 0, negatif dari belakang. - Slicing
[mulai:berhenti:langkah]; angka berhenti tidak ikut. - tuple
(...): tidak bisa diubah; dict{kunci: nilai}: data berlabel; set{...}: tanpa duplikat dan tanpa urutan. len(),sum(),max(),min()bekerja pada daftar.- Comprehension membuat dan menyaring list dalam satu baris.
- List berisi dict adalah cara lazim menyimpan banyak catatan lapangan.
Selanjutnya, di Bab 10: kita sudah punya data dan cara mengolahnya. Sekarang kita belajar membungkus pekerjaan berulang menjadi fungsi, supaya cukup ditulis sekali dan dipakai berkali-kali.