- EN
- ID
Panduan ini untuk siapa
- Pembelajar yang sudah memahami dasar Python dan fundamental OOP
- Developer yang ingin menulis kode lebih cepat dan lebih scalable
- Siapa pun yang mempersiapkan technical interview atau tugas coding yang sadar performa
Apa yang akan Anda pelajari
- Perbedaan perilaku dan performa struktur data bawaan Python
- Dasar Big O untuk analisis kompleksitas waktu dan ruang
- Cara kerja algoritma sorting dan searching dasar di Python
- Kapan memakai operasi built-in versus implementasi algoritma kustom
- Jebakan performa umum dan cara menghindarinya
Mengapa topik ini penting
Kode yang baik bukan hanya benar; kode juga harus cukup efisien untuk ukuran masalahnya. Struktur data dan algoritma membantu Anda menalar performa sebelum aplikasi menjadi lambat atau mahal untuk dijalankan.
Di Python, Anda sering mendapat performa sangat baik dari built-in, tetapi tetap butuh cara berpikir algoritmik. Memahami kompleksitas dan trade-off membantu Anda mengambil keputusan lebih baik saat menangani dataset besar, operasi berulang, atau tugas sensitif waktu.
Konsep inti
Struktur data bawaan dan kompleksitas umumnya
Python menyediakan default yang kuat: list, tuple, set, dan dict.
Intuisi cepat:
list: berurutan, mutable, cocok untuk iterasi dan appendtuple: berurutan, immutable, berguna untuk record tetapset: nilai unik, membership check cepatdict: pemetaan key-value, lookup key cepat
Pola kompleksitas umum (average case):
list.append()-> $O(1)$x in list-> $O(n)$tuple[index]-> $O(1)$x in set-> $O(1)$dict[key]lookup -> $O(1)$
items = [10, 20, 30, 40]
lookup_set = set(items)
print(30 in items) # linear scan
print(30 in lookup_set) # hash lookup
Notasi Big O: bandingkan pertumbuhan, bukan milidetik persis
Big O menjelaskan bagaimana runtime atau memori tumbuh ketika ukuran input meningkat.
Kategori yang berguna:
- $O(1)$ constant
- $O(\log n)$ logarithmic
- $O(n)$ linear
- $O(n \log n)$ kelas sorting efisien
- $O(n^2)$ quadratic
Intuisi contoh:
- Linear search memindai satu per satu -> $O(n)$
- Binary search membagi ruang pencarian tiap langkah -> $O(\log n)$ (butuh data terurut)
Fokus pada tren pertumbuhan; runtime persis bergantung pada hardware dan detail implementasi.
Contoh cepat space complexity:
- Linear search memakai memori tambahan konstan -> $O(1)$ space
- Pendekatan gaya merge dapat mengalokasikan array tambahan -> sering $O(n)$ space
- Operasi in-place (jika memungkinkan) dapat mengurangi overhead memori
Fundamental sorting dan searching
Python punya tool built-in (sorted, .sort()) yang sangat optimal. Pelajari algoritma manual untuk pemahaman dan interview, tetapi utamakan built-in di production kecuali ada kebutuhan khusus.
Linear search dasar:
def linear_search(values, target):
for index, value in enumerate(values):
if value == target:
return index
return -1
Binary search dasar (input harus terurut):
def binary_search(values, target):
left, right = 0, len(values) - 1
while left <= right:
mid = (left + right) // 2
if values[mid] == target:
return mid
if values[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
Panduan langkah demi langkah
Langkah 1 — Pilih struktur data yang tepat untuk pekerjaan
Mulai dari tujuan masalah, bukan dari sintaks.
Gunakan model keputusan sederhana ini:
- Butuh koleksi mutable berurutan ->
list - Butuh item unik / membership cepat ->
set - Butuh field berlabel berdasarkan key ->
dict - Butuh record tetap immutable ->
tuple
emails = ["[email protected]", "[email protected]", "[email protected]"]
unique_emails = set(emails)
print(unique_emails)
Memilih set langsung menghapus duplikasi dengan kode yang bersih.
Langkah 2 — Implementasi dan uji pendekatan searching
Gunakan linear search untuk data tidak terurut atau cek sekali pakai. Gunakan binary search untuk koleksi terurut dengan lookup berulang.
values = [3, 7, 11, 19, 25, 31]
print(linear_search(values, 19))
print(binary_search(values, 19))
Expected output:
3
3
Pilihan algoritma harus sesuai bentuk data dan frekuensi lookup.
Langkah 3 — Bandingkan implementasi sorting
Pelajari sorting manual sederhana, lalu bandingkan dengan built-in Python.
def bubble_sort(values):
arr = values[:]
n = len(arr)
for i in range(n):
for j in range(0, n - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
data = [9, 4, 7, 1, 3]
print(bubble_sort(data))
print(sorted(data))
Expected output:
[1, 3, 4, 7, 9]
[1, 3, 4, 7, 9]
bubble_sort bersifat edukatif ($O(n^2)$), sementara sorted() praktis dan sudah dioptimasi.
Insertion sort (edukatif, sering lebih baik daripada bubble sort pada list kecil yang hampir terurut):
def insertion_sort(values):
arr = values[:]
for i in range(1, len(arr)):
key = arr[i]
j = i - 1
while j >= 0 and arr[j] > key:
arr[j + 1] = arr[j]
j -= 1
arr[j + 1] = key
return arr
Quicksort (konsep divide-and-conquer):
def quicksort(values):
if len(values) <= 1:
return values
pivot = values[len(values) // 2]
left = [v for v in values if v < pivot]
middle = [v for v in values if v == pivot]
right = [v for v in values if v > pivot]
return quicksort(left) + middle + quicksort(right)
Visual complexity cheat sheet:
| Complexity | Typical pattern | |—|—| | $O(1)$ | Hash lookup | | $O(\log n)$ | Binary search | | $O(n)$ | Single pass scan | | $O(n \log n)$ | Efficient comparison sort | | $O(n^2)$ | Nested loops (bubble/insertion worst-case) |
Ringkasan perspektif memori (space complexity):
| Algorithm/Pattern | Typical extra space | |—|—| | Linear search | $O(1)$ | | Binary search (iterative) | $O(1)$ | | Bubble sort | $O(1)$ | | Insertion sort | $O(1)$ | | Quicksort (recursive, average) | $O(\log n)$ stack |
Contoh praktis
Contoh 1 — Deteksi duplikasi cepat pada input besar
Saat memeriksa elemen berulang, set biasanya alat pertama terbaik.
def has_duplicates(values):
seen = set()
for value in values:
if value in seen:
return True
seen.add(value)
return False
print(has_duplicates([1, 2, 3, 4]))
print(has_duplicates([1, 2, 3, 2]))
Expected output:
False
True
Pola ini umum pada validasi, pemrosesan event, dan pipeline pembersihan data.
Contoh 2 — Frequency counting dengan dictionary
Menghitung kemunculan adalah operasi inti dalam analytics dan log.
def frequency_map(words):
counts = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
return counts
tokens = ["python", "data", "python", "api", "data", "python"]
print(frequency_map(tokens))
Expected output:
{'python': 3, 'data': 2, 'api': 1}
Nanti Anda bisa menggantinya dengan collections.Counter, tetapi versi ini membangun pemahaman inti.
Kesalahan umum dan cara menghindarinya
- Memakai
listuntuk membership check yang sering -> Gunakansetatau keydictuntuk lookup rata-rata $O(1)$. - Menerapkan binary search pada data tak terurut -> Urutkan dulu atau pilih linear search.
- Menulis ulang algoritma built-in tanpa kebutuhan -> Utamakan
sorted()dan tool standard library kecuali ada syarat khusus. - Mengabaikan ukuran input saat mengambil keputusan desain -> Perkirakan kompleksitas sebelum memilih algoritma.
- Mengoptimasi terlalu dini tanpa pengukuran -> Mulai dari kode yang jelas, lalu profile bottleneck.
Latihan cepat
- Implementasikan
insertion_sortdi Python dan bandingkan output-nya dengansorted(). - Tulis linear search dan binary search, lalu uji pada list terurut yang sama.
- Buat script yang menghitung frekuensi kata dari sebuah kalimat dan mencetak 3 kata teratas.
Ringkasan utama
- Pilihan struktur data sering memberi peningkatan kecepatan yang lebih besar dibanding micro-optimization.
- Big O membantu Anda memprediksi skalabilitas dan menghindari pola pertumbuhan yang buruk.
- Pahami algoritma dasar untuk reasoning dan interview, tetapi gunakan built-in Python di production sebagai default.
- Keputusan performa sebaiknya didasarkan pada kompleksitas sekaligus pengukuran dunia nyata.
Langkah berikutnya
Lanjut ke Manajemen Paket Python & Ekosistem. Di panduan berikutnya, Anda akan mempelajari pilihan tooling modern (pip, Poetry, PDM, uv, dan lainnya) serta cara mengelola dependency dengan bersih.
No Comments