37. Fungsi Bawaan dan Alat yang Berguna
Python menyediakan koleksi kaya fungsi bawaan yang selalu tersedia tanpa perlu mengimpor modul apa pun. Fungsi-fungsi ini membentuk fondasi pemrograman Python sehari-hari, membantu Anda bekerja secara efisien dengan data, sekuens, dan koleksi. Di bab ini, kita akan mengeksplorasi alat bawaan Python yang paling berguna dan mempelajari cara memanfaatkannya untuk menulis kode yang lebih bersih dan lebih ekspresif.
Memahami Sistem Tipe Python
Sebelum masuk ke fungsi bawaan tertentu, ada baiknya memahami bagaimana Python mengatur tipe datanya. Pengetahuan ini akan membantu Anda memprediksi operasi mana yang bekerja dengan tipe mana dan memahami pesan error saat itu terjadi.
Tipe data Python bisa dipahami dari dua sudut pandang yang saling melengkapi:
Hirarki Tipe: Bagaimana Tipe Saling Berhubungan
Ini menunjukkan bagaimana Python mengelompokkan tipe ke dalam keluarga berdasarkan apa mereka ITU.
Tampilan Berbasis Kapabilitas: Apa yang Bisa Dilakukan Tipe
Untuk fungsi bawaan, yang lebih penting adalah apa yang bisa DILAKUKAN oleh tipe:
Kapabilitas utama:
- Iterable (iterable): Bisa digunakan di loop
for→ Bekerja dengansum(),any(),all(),sorted() - Collection (collection): Iterable dengan
len()→ Bekerja denganlen()dan operatorin - Sequence (sequence): Collection dengan indexing → Mendukung
[index]dan slicing[start:end]
Kenapa Ini Penting
Fungsi bawaan memerlukan kapabilitas tertentu:
| Fungsi | Memerlukan | Bekerja Dengan |
|---|---|---|
len() | Collection | str, list, dict, set, tuple |
sum() | Iterable berisi angka | list, tuple, set, range, generator |
sorted() | Iterable | str, list, dict, set, tuple |
[index] | Sequence | str, list, tuple, range |
Memahami kategori ini membantu Anda:
- Memprediksi fungsi mana yang bekerja dengan tipe mana
- Memahami pesan error seperti "object is not iterable"
- Tahu kapan Anda bisa melakukan indexing (
[0]) vs kapan Anda hanya bisa melakukan loop (for)
37.1) Fungsi Bawaan Umum (len, sum, min, max, abs, round)
Fungsi bawaan Python yang paling sering dipakai membantu Anda melakukan operasi umum pada data tanpa menulis loop atau logika yang rumit. Fungsi-fungsi ini optimal, mudah dibaca, dan menjadi fondasi kode Pythonic.
37.1.1) Mengukur Panjang dengan len()
Fungsi len() mengembalikan jumlah item dalam sebuah collection. Ini bekerja dengan string, list, tuple, dictionary, set, dan tipe collection lainnya.
# Menghitung karakter dalam sebuah string
message = "Hello, World!"
print(len(message)) # Output: 13
# Menghitung elemen dalam sebuah list
scores = [85, 92, 78, 90, 88]
print(len(scores)) # Output: 5
# Menghitung pasangan key-value dalam sebuah dictionary
student = {"name": "Bob", "age": 21, "major": "CS"}
print(len(student)) # Output: 3
# Menghitung item unik dalam sebuah set
unique_ids = {101, 102, 103, 101, 102} # Duplikat dihapus
print(len(unique_ids)) # Output: 3Fungsi len() sangat berguna ketika Anda perlu mengetahui ukuran data sebelum memprosesnya:
# Memproses data berdasarkan ukuran
data = [12, 45, 23, 67, 89, 34]
if len(data) < 5:
print("Not enough data for analysis")
else:
print(f"Analyzing {len(data)} data points") # Output: Analyzing 6 data points
average = sum(data) / len(data)
print(f"Average: {average}") # Output: Average: 45.037.1.2) Menghitung Total dengan sum()
Fungsi sum() menjumlahkan semua angka dalam sebuah iterable. Ini jauh lebih bersih daripada menulis loop untuk mengakumulasi nilai.
# Menjumlahkan sebuah list angka
prices = [19.99, 24.50, 15.75, 32.00]
total = sum(prices)
print(f"Total: ${total}") # Output: Total: $92.24
# Menjumlahkan sebuah tuple
daily_steps = (8500, 10200, 7800, 9500, 11000)
weekly_total = sum(daily_steps)
print(f"Total steps this week: {weekly_total}") # Output: Total steps this week: 47000
# Menjumlahkan sebuah range
total_1_to_100 = sum(range(1, 101))
print(total_1_to_100) # Output: 5050Contoh praktis menggabungkan sum() dan len() untuk menghitung rata-rata:
# Menghitung rata-rata nilai ujian
test_scores = [88, 92, 79, 85, 90, 87]
total_score = sum(test_scores)
num_tests = len(test_scores)
average_score = total_score / num_tests
print(f"Average score: {average_score:.1f}") # Output: Average score: 86.8Batasan penting: sum() hanya bekerja dengan angka. Anda tidak bisa memakainya untuk menggabungkan string atau menggabungkan list:
# Ini memunculkan TypeError
words = ["Hello", " ", "World"]
# sentence = sum(words) # TypeError: unsupported operand type(s)37.1.3) Mencari Nilai Ekstrem dengan min() dan max()
Fungsi min() dan max() mencari nilai terkecil dan terbesar dalam sebuah iterable. Keduanya bekerja dengan angka, string, dan objek apa pun yang bisa dibandingkan.
# Mencari angka minimum dan maksimum
temperatures = [72, 68, 75, 70, 73, 69]
coldest = min(temperatures)
warmest = max(temperatures)
print(f"Temperature range: {coldest}°F to {warmest}°F")
# Output: Temperature range: 68°F to 75°F
# Mencari string minimum dan maksimum (secara alfabet)
names = ["Zoe", "Alice", "Bob", "Charlie"]
first_alphabetically = min(names)
last_alphabetically = max(names)
print(f"First: {first_alphabetically}, Last: {last_alphabetically}")
# Output: First: Alice, Last: ZoeAnda juga bisa memberikan beberapa argumen secara langsung alih-alih sebuah collection:
# Membandingkan nilai individual
lowest = min(45, 23, 67, 12, 89)
highest = max(45, 23, 67, 12, 89)
print(f"Lowest: {lowest}, Highest: {highest}")
# Output: Lowest: 12, Highest: 89
# Berguna untuk membandingkan beberapa nilai spesifik
price1 = 19.99
price2 = 24.50
price3 = 15.75
cheapest = min(price1, price2, price3)
print(f"Cheapest option: ${cheapest}") # Output: Cheapest option: $15.7537.1.4) Mendapatkan Nilai Absolut dengan abs()
Fungsi abs() mengembalikan nilai absolut dari sebuah angka—jaraknya dari nol, selalu positif. Ini berguna ketika Anda peduli pada besarannya tetapi bukan arahnya.
# Nilai absolut dari angka negatif
print(abs(-42)) # Output: 42
print(abs(-3.14)) # Output: 3.14
# Nilai absolut dari angka positif (tidak berubah)
print(abs(42)) # Output: 42
print(abs(3.14)) # Output: 3.14
# Nilai absolut dari nol
print(abs(0)) # Output: 0Salah satu use case umum adalah menghitung selisih ketika arah tidak penting:
# Menghitung perubahan suhu (hanya magnitudo)
morning_temp = 65
evening_temp = 72
temperature_change = abs(evening_temp - morning_temp)
print(f"Temperature changed by {temperature_change}°F")
# Output: Temperature changed by 7°F37.1.5) Membulatkan Angka dengan round()
Fungsi round() membulatkan sebuah angka ke jumlah tempat desimal tertentu. Tanpa argumen kedua, ia membulatkan ke bilangan bulat terdekat.
# Membulatkan ke bilangan bulat terdekat
print(round(3.7)) # Output: 4
print(round(3.2)) # Output: 3
print(round(3.5)) # Output: 4
print(round(4.5)) # Output: 4 (dibulatkan ke bilangan genap terdekat)
# Membulatkan ke tempat desimal tertentu
price = 19.876
print(round(price, 2)) # Output: 19.88 (2 tempat desimal)
print(round(price, 1)) # Output: 19.9 (1 tempat desimal)
# Membulatkan ke tempat desimal negatif (membulatkan ke puluhan, ratusan, dll.)
population = 1234567
print(round(population, -3)) # Output: 1235000 (seribu terdekat)
print(round(population, -4)) # Output: 1230000 (sepuluh ribu terdekat)Catatan tentang nilai tepat di tengah: Saat membulatkan angka yang tepat berada di tengah antara dua bilangan bulat, Python punya aturan khusus. Misalnya, 2.5 tepat di tengah antara 2 dan 3. Anda mungkin mengira ia dibulatkan naik ke 3, tetapi Python membulatkan ke tetangga yang merupakan bilangan genap—dalam kasus ini, 2.
Ini disebut "banker's rounding" atau "round half to even." Ini adalah bagian dari standar IEEE 754 dan membantu mengurangi bias pada banyak operasi pembulatan.
# Nilai tepat di tengah dibulatkan ke bilangan genap terdekat
print(round(0.5)) # Output: 0 (0 genap)
print(round(1.5)) # Output: 2 (2 genap)
print(round(2.5)) # Output: 2 (2 genap)
print(round(3.5)) # Output: 4 (4 genap)
print(round(4.5)) # Output: 4 (4 genap)37.2) Melakukan Enumerasi Sekuens dengan enumerate()
Saat melakukan loop pada sebuah sekuens, Anda sering membutuhkan elemen sekaligus posisinya. Fungsi enumerate() menyediakan keduanya, sehingga tidak perlu variabel penghitung manual.
37.2.1) Masalah dengan Penghitung Manual
Sebelum mempelajari enumerate(), programmer sering memakai variabel penghitung untuk melacak posisi:
# Pendekatan penghitung manual (berfungsi tapi tidak ideal)
fruits = ["apple", "banana", "cherry", "date"]
index = 0
for fruit in fruits:
print(f"{index}: {fruit}")
index += 1
# Output:
# 0: apple
# 1: banana
# 2: cherry
# 3: datePendekatan ini punya beberapa kekurangan:
- Variabel tambahan yang harus dikelola (
index) - Mudah lupa menambah penghitungnya
37.2.2) Menggunakan enumerate() untuk Posisi dan Nilai
Fungsi enumerate() menyelesaikan masalah ini dengan elegan. Ia menerima sebuah iterable dan mengembalikan pasangan (index, element):
# Menggunakan enumerate() - lebih bersih dan lebih Pythonic
fruits = ["apple", "banana", "cherry", "date"]
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
# Output:
# 0: apple
# 1: banana
# 2: cherry
# 3: dateSintaks for index, fruit in enumerate(fruits) menggunakan unpacking tuple (seperti yang kita pelajari di Bab 15). Pada setiap iterasi, enumerate() menyediakan tuple seperti (0, "apple"), yang di-unpack ke variabel index dan fruit.
Berikut adalah apa yang sebenarnya dihasilkan oleh enumerate():
# Melihat output enumerate secara langsung
fruits = ["apple", "banana", "cherry"]
enumerated = list(enumerate(fruits))
print(enumerated)
# Output: [(0, 'apple'), (1, 'banana'), (2, 'cherry')]37.2.3) Memulai Enumerasi dari Angka yang Berbeda
Secara default, enumerate() mulai menghitung dari 0. Anda bisa menentukan angka awal yang berbeda dengan parameter start:
# Mulai menghitung dari 1 (berguna untuk tampilan)
tasks = ["Write code", "Test code", "Deploy code"]
for number, task in enumerate(tasks, start=1):
print(f"Step {number}: {task}")
# Output:
# Step 1: Write code
# Step 2: Test code
# Step 3: Deploy codeIni sangat berguna saat menampilkan daftar bernomor kepada pengguna, karena biasanya mereka mengharapkan penghitungan dimulai dari 1:
# Menu dengan opsi bernomor
menu_items = ["New Game", "Load Game", "Settings", "Quit"]
print("Main Menu:")
for number, item in enumerate(menu_items, start=1):
print(f"{number}. {item}")
# Output:
# Main Menu:
# 1. New Game
# 2. Load Game
# 3. Settings
# 4. Quit37.2.4) enumerate() dengan String dan Iterable Lainnya
Fungsi enumerate() bekerja dengan iterable apa pun, bukan hanya list:
# Melakukan enumerasi karakter dalam sebuah string
word = "Python"
for position, letter in enumerate(word):
print(f"Letter {position}: {letter}")
# Output:
# Letter 0: P
# Letter 1: y
# Letter 2: t
# Letter 3: h
# Letter 4: o
# Letter 5: n
# Melakukan enumerasi sebuah tuple
coordinates = (10, 20, 30, 40)
for index, value in enumerate(coordinates):
print(f"Coordinate {index}: {value}")
# Output:
# Coordinate 0: 10
# Coordinate 1: 20
# Coordinate 2: 30
# Coordinate 3: 40Fungsi enumerate() membuat kode lebih mudah dibaca dan lebih kecil kemungkinan error. Kapan pun Anda membutuhkan posisi dan nilai dalam sebuah loop, pilih enumerate() daripada mengelola penghitung secara manual.
37.3) Menggabungkan Sekuens dengan zip()
Fungsi zip() menggabungkan beberapa iterable elemen demi elemen, membuat pasangan (atau tuple) dari elemen yang bersesuaian. Ini sangat berharga saat Anda perlu memproses data terkait dari sekuens terpisah secara bersamaan.
37.3.1) Memahami Cara Kerja zip()
Fungsi zip() menerima dua atau lebih iterable dan mengembalikan iterator berisi tuple, di mana setiap tuple berisi satu elemen dari masing-masing iterable masukan:
# Menggabungkan dua list
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
combined = list(zip(names, ages))
print(combined)
# Output: [('Alice', 25), ('Bob', 30), ('Charlie', 35)]Nama "zip" berasal dari resleting pada pakaian—ia menggabungkan dua sisi terpisah menjadi satu struktur yang menyatu, elemen demi elemen.
Berikut representasi visual tentang bagaimana zip() memasangkan elemen:
37.3.2) Menggunakan zip() dalam Loop
Penggunaan paling umum dari zip() adalah di loop for, ketika Anda perlu melakukan iterasi pada beberapa sekuens secara bersamaan:
# Memproses data paralel
students = ["Alice", "Bob", "Charlie", "Diana"]
scores = [92, 85, 88, 95]
for student, score in zip(students, scores):
print(f"{student} scored {score}")
# Output:
# Alice scored 92
# Bob scored 85
# Charlie scored 88
# Diana scored 95Ini jauh lebih bersih daripada menggunakan indeks:
# Tanpa zip() - lebih kompleks dan lebih rentan error
students = ["Alice", "Bob", "Charlie", "Diana"]
scores = [92, 85, 88, 95]
for i in range(len(students)):
print(f"{students[i]} scored {scores[i]}")
# Output yang sama, tetapi lebih banyak kode dan potensi error indeks37.3.3) Menangani Sekuens dengan Panjang Berbeda
Ketika sekuens masukan memiliki panjang yang berbeda, zip() berhenti saat sekuens terpendek habis:
# Sekuens dengan panjang tidak sama
names = ["Alice", "Bob", "Charlie", "Diana"]
ages = [25, 30] # Hanya 2 umur
for name, age in zip(names, ages):
print(f"{name} is {age} years old")
# Output:
# Alice is 25 years old
# Bob is 30 years old
# (Charlie dan Diana tidak diproses)Perilaku ini mencegah error tetapi bisa menyebabkan hilangnya data secara diam-diam jika Anda tidak hati-hati. Selalu verifikasi bahwa sekuens Anda memiliki panjang yang diharapkan:
# Memeriksa ketidakcocokan panjang
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30]
if len(names) != len(ages):
print(f"Warning: {len(names)} names but {len(ages)} ages")
print("Only processing the first", min(len(names), len(ages)), "entries")
# Output: Warning: 3 names but 2 ages
# Output: Only processing the first 2 entries
# Lanjutkan dengan zip() - ia akan berhenti pada yang terpendek
for name, age in zip(names, ages):
print(f"{name} is {age} years old")37.3.4) Melakukan Zip pada Lebih dari Dua Sekuens
Fungsi zip() bisa menggabungkan berapa pun jumlah iterable:
# Menggabungkan tiga sekuens
products = ["Laptop", "Mouse", "Keyboard"]
prices = [999.99, 24.99, 79.99]
quantities = [5, 20, 15]
print("Inventory Report:")
for product, price, quantity in zip(products, prices, quantities):
total_value = price * quantity
print(f"{product}: ${price} × {quantity} = ${total_value:.2f}")
# Output:
# Inventory Report:
# Laptop: $999.99 × 5 = $4999.95
# Mouse: $24.99 × 20 = $499.80
# Keyboard: $79.99 × 15 = $1199.8537.3.5) Membuat Dictionary dengan zip()
Pola yang kuat adalah menggunakan zip() untuk membuat dictionary dari sekuens key dan value yang terpisah:
# Membuat dictionary dari dua list
keys = ["name", "age", "city"]
values = ["Alice", 25, "Boston"]
person = dict(zip(keys, values))
print(person)
# Output: {'name': 'Alice', 'age': 25, 'city': 'Boston'}37.4) Agregasi Boolean dengan any() dan all()
Fungsi any() dan all() menguji kondisi di seluruh iterable, dan mengembalikan satu hasil boolean. Keduanya adalah alat yang kuat untuk validasi dan pengambilan keputusan berdasarkan banyak kondisi.
37.4.1) Memahami any(): True jika Setidaknya Satu Elemen True
Fungsi any() mengembalikan True jika setidaknya satu elemen dalam sebuah iterable bernilai truthy (dievaluasi menjadi True). Jika semua elemen bernilai falsy, ia mengembalikan False:
# Contoh any() dasar
print(any([True, False, False])) # Output: True (setidaknya satu True)
print(any([False, False, False])) # Output: False (semua False)
print(any([False, True, True])) # Output: True (beberapa nilai True)
# Iterable kosong
print(any([])) # Output: False (tidak ada elemen yang bisa True)Fungsi any() menggunakan aturan truthiness Python (seperti yang kita pelajari di Bab 7). Angka bukan nol, string tidak kosong, dan collection tidak kosong adalah truthy:
# any() dengan nilai truthy/falsy yang berbeda
print(any([0, 0, 1])) # Output: True (1 adalah truthy)
print(any([0, 0, 0])) # Output: False (semua nol adalah falsy)
print(any(["", "", "text"])) # Output: True ("text" adalah truthy)
print(any(["", "", ""])) # Output: False (string kosong adalah falsy)37.4.2) Penggunaan Praktis any()
Contoh: Mengecek apakah ada kondisi yang terpenuhi
# Cek apakah ada nilai yang tidak lulus (di bawah 60)
scores = [75, 82, 55, 90, 88]
has_failing_grade = any(score < 60 for score in scores)
if has_failing_grade:
print("Warning: At least one failing grade")
# Output: Warning: At least one failing grade
else:
print("All grades are passing")37.4.3) Memahami all(): True Hanya jika Semua Elemen True
Fungsi all() mengembalikan True hanya jika semua elemen dalam sebuah iterable bernilai truthy. Jika ada elemen yang falsy, ia mengembalikan False:
# Contoh all() dasar
print(all([True, True, True])) # Output: True (semua True)
print(all([True, False, True])) # Output: False (satu False)
print(all([True, True, False])) # Output: False (satu False)
# Iterable kosong
print(all([])) # Output: True (vacuous truth - tidak ada elemen False)Perilaku pada iterable kosong mungkin terasa mengejutkan: all([]) mengembalikan True. Ini disebut vacuous truth—pernyataan "semua elemen True" secara teknis benar ketika tidak ada elemen yang bisa menyangkalnya.
# all() dengan nilai truthy/falsy yang berbeda
print(all([1, 2, 3])) # Output: True (semua bukan nol)
print(all([1, 0, 3])) # Output: False (0 adalah falsy)
print(all(["a", "b", "c"])) # Output: True (semua tidak kosong)
print(all(["a", "", "c"])) # Output: False (string kosong adalah falsy)37.4.4) Penggunaan Praktis all()
Contoh: Memvalidasi bahwa semua kondisi terpenuhi
# Cek apakah semua nilai lulus (60 atau lebih)
scores = [75, 82, 68, 90, 88]
all_passing = all(score >= 60 for score in scores)
if all_passing:
print("Congratulations! All grades are passing")
# Output: Congratulations! All grades are passing
else:
print("Some grades need improvement")37.4.5) Evaluasi Short-Circuit pada any() dan all()
Baik any() maupun all() menggunakan short-circuit evaluation (seperti yang kita pelajari di Bab 9). Mereka berhenti mengecek begitu hasilnya sudah bisa ditentukan:
# Fungsi yang mencetak saat dipanggil (untuk menunjukkan eksekusi)
def is_positive(n):
print(f"Checking {n}")
return n > 0
# any() berhenti pada True pertama
print("Testing any():")
numbers = [0, 0, 1, 2, 3]
result = any(is_positive(n) for n in numbers)
# Output:
# Testing any():
# Checking 0
# Checking 0
# Checking 1
# (Stops here - doesn't check 2 or 3)
print(f"Result: {result}") # Output: Result: True
print("\nTesting all():")
numbers = [1, 2, 0, 3, 4]
result = all(is_positive(n) for n in numbers)
# Output:
# Testing all():
# Checking 1
# Checking 2
# Checking 0
# (Stops here - doesn't check 3 or 4)
print(f"Result: {result}") # Output: Result: FalseIni membuat any() dan all() efisien—mereka tidak membuang waktu mengecek elemen setelah hasilnya sudah ditentukan.
37.5) Mengurutkan dengan sorted() dan Key Kustom
Fungsi sorted() membuat list baru yang sudah diurutkan dari iterable apa pun. Tidak seperti method .sort() (yang hanya bekerja pada list dan memodifikasinya secara in-place), sorted() bekerja dengan iterable apa pun dan selalu mengembalikan list baru.
37.5.1) Pengurutan Dasar dengan sorted()
Fungsi sorted() mengatur elemen dalam urutan naik (ascending) secara default:
# Mengurutkan angka
numbers = [42, 17, 93, 8, 55]
sorted_numbers = sorted(numbers)
print(sorted_numbers) # Output: [8, 17, 42, 55, 93]
# List asli tidak berubah
print(numbers) # Output: [42, 17, 93, 8, 55]
# Mengurutkan string (secara alfabet)
names = ["Charlie", "Alice", "Bob", "Diana"]
sorted_names = sorted(names)
print(sorted_names) # Output: ['Alice', 'Bob', 'Charlie', 'Diana']Fungsi sorted() bekerja dengan iterable apa pun, bukan hanya list:
# Mengurutkan tuple (mengembalikan list)
coordinates = (5, 2, 8, 1, 9)
sorted_coords = sorted(coordinates)
print(sorted_coords) # Output: [1, 2, 5, 8, 9]
# Mengurutkan string (mengembalikan list karakter)
word = "python"
sorted_letters = sorted(word)
print(sorted_letters) # Output: ['h', 'n', 'o', 'p', 't', 'y']
# Mengurutkan set (mengembalikan list terurut)
unique_numbers = {5, 8, 2, 1}
sorted_unique = sorted(unique_numbers)
print(sorted_unique) # Output: [1, 2, 5, 8]37.5.2) Pengurutan Terbalik
Gunakan parameter reverse=True untuk mengurutkan dalam urutan turun (descending):
# Urutan menurun untuk angka
scores = [85, 92, 78, 95, 88]
highest_first = sorted(scores, reverse=True)
print(highest_first) # Output: [95, 92, 88, 85, 78]
# Urutan menurun untuk string (alfabet terbalik)
names = ["Charlie", "Alice", "Bob", "Diana"]
reverse_alpha = sorted(names, reverse=True)
print(reverse_alpha) # Output: ['Diana', 'Charlie', 'Bob', 'Alice']37.5.3) Memahami Parameter key
Parameter key adalah tempat sorted() menjadi benar-benar powerful. Ini mengubah cara Python membandingkan elemen saat pengurutan.
Apa itu parameter key?
Parameter key menerima sebuah fungsi(function). Python memanggil fungsi ini pada setiap elemen untuk mengekstrak sebuah "comparison key", lalu mengurutkan berdasarkan key ini alih-alih elemen aslinya.
Cara kerjanya langkah demi langkah:
- Python memanggil fungsi key pada setiap elemen
- Python mengumpulkan semua key
- Python mengurutkan dengan membandingkan key tersebut
- Python mengembalikan elemen asli dalam urutan baru
# Contoh: Mengurutkan berdasarkan panjang
words = ["python", "is", "awesome"]
# Langkah 1: Python memanggil len() pada setiap kata
# len("python") → 6
# len("is") → 2
# len("awesome") → 7
# Langkah 2: Python memiliki key ini: [6, 2, 7]
# Langkah 3: Python mengurutkan key: [2, 6, 7]
# Langkah 4: Python mengembalikan words dalam urutan itu: ["is", "python", "awesome"]
result = sorted(words, key=len)
print(result) # Output: ['is', 'python', 'awesome']Memvisualisasikan fungsi key:
Apa yang bisa menjadi fungsi key?
Fungsi key harus:
- Menerima satu argumen (elemen yang sedang diurutkan)
- Mengembalikan nilai yang bisa dibandingkan oleh Python (angka, string, tuple, dll.)
# Fungsi bawaan sangat cocok
sorted(numbers, key=abs) # Urutkan berdasarkan nilai absolut
sorted(words, key=len) # Urutkan berdasarkan panjang
sorted(names, key=str.lower) # Urutkan tanpa membedakan huruf besar-kecil
# Fungsi buatan Anda sendiri
def first_letter(word):
return word[0]
sorted(words, key=first_letter) # Urutkan berdasarkan huruf pertama
# Fungsi lambda (Bab 23)
sorted(words, key=lambda w: w[-1]) # Urutkan berdasarkan huruf terakhirPenting: Fungsi key dipanggil sekali per elemen
# Mendemonstrasikan kapan fungsi key dipanggil
def show_key(word):
print(f"Getting key for: {word}")
return len(word)
words = ["cat", "elephant", "dog"]
result = sorted(words, key=show_key)
# Output:
# Getting key for: cat
# Getting key for: elephant
# Getting key for: dog
print(result) # Output: ['cat', 'dog', 'elephant']Penting: Fungsi key dipanggil sekali per elemen
Perhatikan bahwa show_key dipanggil tepat satu kali untuk setiap kata, bukan berulang kali selama perbandingan. Python efisien—ia mengekstrak semua key terlebih dahulu, menyimpannya dalam cache, lalu mengurutkan menggunakan key yang sudah di-cache.
Anggap key sebagai menjawab: "Aspek apa yang harus saya bandingkan?"
key=len→ "Bandingkan berdasarkan panjang"key=abs→ "Bandingkan berdasarkan nilai absolut"key=str.lower→ "Bandingkan seolah-olah semuanya huruf kecil"key=lambda x: x[1]→ "Bandingkan berdasarkan elemen kedua"
Parameter key memungkinkan Anda mengurutkan berdasarkan properti apa pun dari elemen Anda, membuat sorted() sangat serbaguna.
37.5.4) Mengurutkan dengan Fungsi Bawaan sebagai Key
Fungsi bawaan Python menjadi fungsi key yang sangat baik:
# Mengurutkan berdasarkan nilai absolut
numbers = [-5, 2, -8, 1, -3, 7]
sorted_by_magnitude = sorted(numbers, key=abs)
print(sorted_by_magnitude) # Output: [1, 2, -3, -5, 7, -8]
# Mengurutkan string tanpa membedakan huruf besar-kecil
names = ["alice", "Bob", "CHARLIE", "diana"]
sorted_case_insensitive = sorted(names, key=str.lower)
print(sorted_case_insensitive) # Output: ['alice', 'Bob', 'CHARLIE', 'diana']37.5.5) Mengurutkan Struktur Data Kompleks
Saat mengurutkan list berisi tuple atau list, Anda bisa menggunakan indexing untuk menentukan elemen mana yang akan dijadikan dasar pengurutan:
# Mengurutkan tuple berdasarkan elemen kedua
students = [
("Alice", 92),
("Bob", 85),
("Charlie", 88),
("Diana", 95)
]
# Urutkan berdasarkan skor (elemen kedua)
by_score = sorted(students, key=lambda student: student[1])
print(by_score)
# Output: [('Bob', 85), ('Charlie', 88), ('Alice', 92), ('Diana', 95)]
# Urutkan berdasarkan skor menurun
by_score_desc = sorted(students, key=lambda student: student[1], reverse=True)
print(by_score_desc)
# Output: [('Diana', 95), ('Alice', 92), ('Charlie', 88), ('Bob', 85)]Catatan: Kita menggunakan lambda di sini (seperti yang kita pelajari di Bab 23). Lambda adalah fungsi anonim kecil. Ekspresi lambda student: student[1] membuat fungsi yang menerima tuple student dan mengembalikan elemen keduanya (skor).
37.5.6) Pengurutan Multi-Level
Anda bisa mengurutkan berdasarkan beberapa kriteria dengan mengembalikan tuple dari fungsi key. Python membandingkan tuple elemen demi elemen, dari kiri ke kanan:
Cara kerja perbandingan tuple:
Saat Python membandingkan dua tuple, ia mengikuti aturan ini:
- Bandingkan elemen pertama. Jika berbeda, perbandingan selesai.
- Jika elemen pertama sama, bandingkan elemen kedua.
- Jika elemen kedua sama, bandingkan elemen ketiga.
- Lanjutkan sampai menemukan perbedaan atau kehabisan elemen.
# Contoh perbandingan tuple
print((1, 'a') < (2, 'z')) # Output: True (1 < 2, jadi True langsung)
print((1, 'z') < (1, 'a')) # Output: False (1 == 1, jadi bandingkan 'z' < 'a')
print((1, 'a') < (1, 'a')) # Output: False (kedua tuple sama)
print((1, 2, 9) < (1, 3, 1)) # Output: True (1 == 1, lalu 2 < 3)Ini membuat tuple sempurna untuk pengurutan multi-level—Python secara otomatis menangani logika "bandingkan kriteria pertama, lalu kedua, lalu ketiga" untuk Anda:
# Urutkan berdasarkan beberapa kriteria
students = [
("Alice", "Smith", 92),
("Bob", "Jones", 85),
("Alice", "Brown", 88),
("Charlie", "Smith", 85)
]
# Urutkan berdasarkan nama depan, lalu nama belakang
by_name = sorted(students, key=lambda s: (s[0], s[1]))
print("By name:")
for student in by_name:
print(f" {student}")
# Output:
# By name:
# ('Alice', 'Brown', 88)
# ('Alice', 'Smith', 92)
# ('Bob', 'Jones', 85)
# ('Charlie', 'Smith', 85)
# Urutkan berdasarkan skor menurun, lalu nama menaik
by_score_then_name = sorted(students, key=lambda s: (-s[2], s[0]))
print("\nBy score (high to low), then name:")
for student in by_score_then_name:
print(f" {student}")
# Output:
# By score (high to low), then name:
# ('Alice', 'Smith', 92)
# ('Alice', 'Brown', 88)
# ('Bob', 'Jones', 85)
# ('Charlie', 'Smith', 85)Catatan: Untuk mengurutkan satu kriteria menurun dan yang lain menaik, kita menegatifkan nilai numeriknya (-s[2]). Ini bekerja karena menegatifkan membalik urutan pengurutan untuk angka. Pada contoh di atas, -s[2] mengurutkan skor dari tertinggi ke terendah, sedangkan s[0] mengurutkan nama dari A sampai Z.
37.5.7) Menggunakan Fungsi Helper untuk Key yang Kompleks
Saat logika pengurutan menjadi kompleks, mendefinisikan fungsi helper membuat kode lebih mudah dibaca dan dipelihara. Anda kemudian bisa menggunakan fungsi helper ini di dalam fungsi key Anda.
Contoh: Mengurutkan file berdasarkan ekstensi
Misalkan Anda ingin mengelompokkan file berdasarkan ekstensi (.csv, .jpg, .pdf, dll.), dan di dalam setiap grup, mengurutkan secara alfabet berdasarkan nama file. Fungsi key perlu mengekstrak ekstensi file, yang memerlukan beberapa manipulasi string.
# Urutkan file berdasarkan ekstensi, lalu berdasarkan nama
files = [
"report.pdf",
"data.csv",
"image.jpg",
"notes.txt",
"backup.csv",
"photo.jpg"
]
# Ekstrak ekstensi untuk pengurutan
def get_extension(filename):
"""Mengekstrak ekstensi file dari sebuah filename."""
return filename.split(".")[-1] # Pisahkan dengan "." dan ambil bagian terakhir
# Gunakan fungsi helper di dalam key
sorted_files = sorted(files, key=lambda f: (get_extension(f), f))
print("Files sorted by extension, then name:")
for file in sorted_files:
print(f" {file}")
# Output:
# Files sorted by extension, then name:
# backup.csv # csv files first (alphabetically)
# data.csv # csv files first (alphabetically)
# image.jpg # jpg files next
# photo.jpg # jpg files next
# report.pdf # pdf files next
# notes.txt # txt files lastCara kerjanya:
- Fungsi key
lambda f: (get_extension(f), f)mengembalikan tuple untuk setiap filename - Untuk "report.pdf", ia mengembalikan
("pdf", "report.pdf") - Untuk "data.csv", ia mengembalikan
("csv", "data.csv") - Python mengurutkan berdasarkan elemen pertama dari tuple (ekstensi), lalu berdasarkan elemen kedua (filename lengkap)
- Ini mengelompokkan file berdasarkan ekstensi dan mengurutkan secara alfabet di dalam tiap grup
Kenapa memakai fungsi helper?
Bandingkan keterbacaannya:
# Tanpa fungsi helper - lebih sulit dipahami
sorted_files = sorted(files, key=lambda f: (f.split(".")[-1], f))
# Dengan fungsi helper - maksudnya lebih jelas
sorted_files = sorted(files, key=lambda f: (get_extension(f), f))Fungsi helper membuat kode Anda self-documenting. Siapa pun yang membaca get_extension(f) langsung paham apa yang terjadi, sedangkan f.split(".")[-1] memerlukan parsing mental.
37.5.8) sorted() vs .sort(): Kapan Menggunakan Masing-Masing
Python menyediakan dua cara untuk mengurutkan:
sorted()- Fungsi yang mengembalikan list baru yang sudah diurutkan.sort()- Method list yang mengurutkan in-place
# sorted() - membuat list baru, yang asli tidak berubah
numbers = [3, 1, 4, 1, 5]
sorted_numbers = sorted(numbers)
print(f"Original: {numbers}") # Output: Original: [3, 1, 4, 1, 5]
print(f"Sorted: {sorted_numbers}") # Output: Sorted: [1, 1, 3, 4, 5]
# .sort() - memodifikasi list in-place, mengembalikan None
numbers = [3, 1, 4, 1, 5]
result = numbers.sort()
print(f"Modified: {numbers}") # Output: Modified: [1, 1, 3, 4, 5]
print(f"Return value: {result}") # Output: Return value: NoneKapan menggunakan sorted():
- Anda perlu mempertahankan urutan asli
- Anda mengurutkan sesuatu selain list (tuple, string, set, dll.)
- Anda ingin mengurutkan dan melakukan assignment dalam satu ekspresi
Kapan menggunakan .sort():
- Anda punya list dan tidak butuh urutan asli
- Anda ingin menghemat memori (tidak membuat list baru)
- Anda mengurutkan list besar secara in-place untuk efisiensi
Fungsi sorted() adalah salah satu alat Python yang paling serbaguna. Dikombinasikan dengan parameter key, ia bisa menangani hampir semua kebutuhan pengurutan, dari pengurutan angka sederhana sampai pengurutan multi-kriteria yang kompleks pada struktur data bertingkat.
Bab ini telah membekali Anda dengan fungsi bawaan dan alat esensial Python. Anda telah belajar cara:
- Memahami hirarki tipe Python dan memprediksi operasi mana yang bekerja dengan tipe mana
- Menggunakan fungsi fundamental seperti
len(),sum(),min(),max(),abs(), danround()untuk operasi umum - Melakukan iterasi dengan informasi posisi menggunakan
enumerate() - Memproses sekuens paralel secara bersamaan dengan
zip() - Membuat keputusan lintas collection menggunakan
any()danall() - Mengurutkan data secara fleksibel dengan
sorted()dan fungsi key kustom
Alat-alat ini membentuk fondasi kode Python yang idiomatik. Mereka efisien, mudah dibaca, dan menangani edge case dengan benar. Saat Anda terus memrogram, Anda akan sering memakai fungsi-fungsi ini—mereka adalah building blocks yang membuat kode Python elegan dan ekspresif.
Di bab berikutnya, kita akan mengeksplorasi decorator, yang memungkinkan Anda memodifikasi dan meningkatkan perilaku fungsi(function) dengan cara yang powerful, melanjutkan konsep fungsi kelas-satu yang kita pelajari di Bab 23.