Data Structures
Bab yang paling menentukan apakah kodemu terasa seperti Python atau seperti Java bersintaks Python.
Intisari
- Comprehension adalah idiom paling khas Python. Kalau belum refleks, kodemu belum terasa Python.
- Empat bentuk:
[...]list,{k: v ...}dict,{...}set,(...)generator. - Generator (kurung biasa) itu lazy โ hemat memori untuk data besar, tapi hanya bisa dilewati sekali.
- Slicing
x[a:b:c]berlaku untuk semua urutan, dan tidak pernah error kalau indeksnya kelewatan. - Unpacking (
a, *sisa = ...) menghapus banyak kode indeks manual.
Comprehension: inti dari bab ini
Bentuk dasarnya
[ekspresi for item in sumber if kondisi]
Baca dari kiri: "ambil ekspresi, untuk tiap item di sumber, kalau kondisi terpenuhi."
# Cara imperatif (masih terbaca, tapi bukan gaya Python)
hasil = []
for x in angka:
if x > 0:
hasil.append(x * 2)
# Comprehension
hasil = [x * 2 for x in angka if x > 0]
Empat variannya
[x * 2 for x in items] # list โ [2, 4, 6]
{x.id: x for x in items} # dict โ {"a": <obj>, ...}
{x.kategori for x in items} # set โ {"a", "b"} โ otomatis unik
(x * 2 for x in items) # generator โ lazy, belum menghitung apa pun
Kapan pakai generator: saat sumber datanya besar atau tak terbatas, dan kamu hanya akan
melewatinya sekali. sum(x.skor for x in juta_dokumen) tidak pernah membuat list
berisi sejuta angka di memori โ ia menjumlahkan sambil jalan.
Bersarang dan berkondisi ganda
# dua for โ urutannya sama seperti kalau ditulis bertingkat
[sel for baris in matriks for sel in baris] # ratakan matriks
# if di depan = memilih nilai (bukan menyaring)
[x if x > 0 else 0 for x in angka] # ganti negatif jadi 0
Batasnya: kalau comprehension-mu sudah punya dua for plus dua if,
ia sudah lebih sulit dibaca daripada loop biasa. Comprehension bukan lomba memampatkan kode โ
pakai selama masih terbaca dalam satu tarikan napas.
List: operasi yang sering dipakai
x = [3, 1, 2]
x.append(4) # [3, 1, 2, 4] โ tambah di akhir
x.extend([5, 6]) # gabung list lain
x.insert(0, 9) # sisip di indeks 0
x.pop() # ambil & hapus elemen terakhir
x.remove(1) # hapus berdasarkan NILAI (error kalau tidak ada)
x.sort() # urutkan DI TEMPAT, mengembalikan None
y = sorted(x, key=len, reverse=True) # bikin list BARU yang terurut
Jebakan klasik: x = x.sort() membuat x jadi None.
Aturan umumnya di Python: method yang mengubah objek di tempat mengembalikan None.
Kalau kamu butuh hasilnya, pakai fungsi sorted().
Slicing
x = [0, 1, 2, 3, 4, 5]
x[1:4] # [1, 2, 3] โ awal inklusif, akhir eksklusif
x[:3] # [0, 1, 2]
x[3:] # [3, 4, 5]
x[-2:] # [4, 5] โ dua terakhir
x[::2] # [0, 2, 4] โ tiap dua
x[::-1] # [5, 4, 3, 2, 1, 0] โ dibalik
x[100:200] # [] โ TIDAK error, cuma kosong
Slicing berlaku untuk list, str, dan tuple dengan aturan yang sama persis.
Dict
d = {"nama": "Budi", "umur": 30}
d["nama"] # error kalau key tidak ada
d.get("email") # None kalau tidak ada
d.get("email", "-") # nilai default
d.setdefault("tag", []) # ambil, atau bikin kalau belum ada
d.keys() / d.values() / d.items()
"nama" in d # cek key โ cepat, O(1)
d | {"kota": "Bandung"} # gabung, hasilkan dict BARU (Python 3.9+)
{**default, **override} # gabung, cara lama yang masih umum
Dict Python menjaga urutan penyisipan sejak versi 3.7. Kamu boleh mengandalkan itu.
Set
a = {1, 2, 3}
b = {3, 4, 5}
a | b # {1,2,3,4,5} gabungan
a & b # {3} irisan
a - b # {1,2} selisih
a ^ b # {1,2,4,5} yang hanya ada di salah satu
3 in a # cek keanggotaan โ O(1), jauh lebih cepat daripada list
Trik yang sering berguna: untuk menghapus duplikat sambil menjaga urutan asli,
pakai list(dict.fromkeys(items)). set() menghapus duplikat tapi
mengacak urutannya.
Unpacking
a, b = 1, 2
a, b = b, a # tukar tanpa variabel bantu
pertama, *sisa = [1, 2, 3, 4] # pertama=1, sisa=[2,3,4]
*awal, terakhir = [1, 2, 3, 4] # awal=[1,2,3], terakhir=4
a, _, c = (1, 2, 3) # _ = konvensi "tidak dipakai"
def f(*args, **kwargs): ... # terima argumen sebanyak apa pun
f(*daftar, **kamus) # sebarkan saat memanggil
Fungsi bawaan yang sering dipasangkan
| Fungsi | Fungsinya | Contoh |
|---|---|---|
len | Jumlah elemen | len(items) |
sum | Jumlahkan | sum(x.skor for x in items) |
min / max | Ekstrem, bisa dengan key | max(docs, key=lambda d: d.skor) |
any / all | Ada yang benar / semua benar | any(d.valid for d in docs) |
sorted | Urutkan jadi list baru | sorted(docs, key=lambda d: -d.skor) |
enumerate | Pasangkan indeks | enumerate(items, start=1) |
zip | Gabungkan sejajar | zip(nama, umur) |
reversed | Balik urutan (lazy) | reversed(items) |
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.