Bab 9 — Struktur Data Bawaan: Wadah untuk Data Pohon, Ikan, dan Ternak

Seri B2 — Fondasi Bahasa Python

CatatanDi bab ini, Anda akan:
  • Memakai list untuk daftar yang bisa diubah
  • Mengambil potongan list dengan slicing
  • Mengenal tuple (daftar tetap), dict (data berlabel), dan set (tanpa duplikat)
  • Membuat list baru dalam satu baris dengan comprehension
  • Menyimpan data beberapa pohon sekaligus

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] = 820 mengganti isi nomor 0.
  • x in daftar menjawab True atau False: 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.

Nomor urut list ada dua: dari depan (mulai 0) dan dari belakang (mulai -1). Potongan [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.7
Traceback (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"] = True menambah atau mengubah.
  • .get("warna", "belum dicatat") aman: bila label tidak ada, ia mengembalikan nilai cadangan.
  • .items() memberi pasangan label dan isi untuk dipakai di for.

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.

TipTIPS

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" adalah if satu 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

  1. Buat list berisi bobot lima ekor sapi (angka bebas). Cetak bobot terberat, bobot teringan, dan rata-ratanya.
  2. Dari list [480, 500, 510, 520, 530, 540], ambil dengan slicing: tiga terakhir, dan tiga angka pertama dibalik.
  3. Buat dict untuk satu kolam dengan label nama, jumlah_ikan, bobot_rata_g, dan siap_panen (hasil perbandingan). Cetak semua isinya dengan for dan .items().
  4. 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.