14. List: Koleksi Item yang Terurut
Sejauh ini di buku ini, kita sudah bekerja dengan potongan data individual: angka tunggal, string, dan nilai boolean. Tapi program nyata sering perlu bekerja dengan kumpulan item yang saling terkait—daftar nama siswa, serangkaian pembacaan suhu, kumpulan harga produk, atau urutan perintah pengguna. List Python adalah alat fundamental untuk menyimpan dan bekerja dengan koleksi data yang terurut.
List adalah sebuah sekuens(sequence) yang dapat menampung banyak item dalam urutan tertentu. Berbeda dengan string (yang hanya bisa berisi karakter), list bisa berisi tipe data apa pun: angka, string, boolean, atau bahkan list lain. List juga bersifat mutable, artinya kamu bisa mengubah isinya setelah dibuat—menambahkan item, menghapus item, atau memodifikasi item yang sudah ada.
Di bab ini, kita akan mengeksplor cara membuat list, mengakses elemennya, memodifikasinya, dan menggunakannya untuk menyelesaikan masalah pemrograman yang praktis. Di akhir, kamu akan paham kenapa list adalah salah satu struktur data Python yang paling kuat dan paling sering digunakan.
14.1) Membuat List dan Mengakses Elemen
14.1.1) Membuat List dengan Kurung Siku
Cara paling umum untuk membuat list adalah dengan menuliskan item di dalam kurung siku [], dengan item dipisahkan oleh koma. Berikut contoh sederhana:
# List nama siswa
students = ["Alice", "Bob", "Charlie", "Diana"]
print(students) # Output: ['Alice', 'Bob', 'Charlie', 'Diana']Perhatikan bagaimana Python menampilkan list: Python menampilkan kurung siku dan memberi tanda kutip di sekitar setiap string. Ini adalah representasi(representation) dari list—bagaimana Python menunjukkan apa yang ada di dalamnya.
List dapat berisi tipe data apa pun. Berikut list nilai ujian:
# List skor integer
scores = [85, 92, 78, 95, 88]
print(scores) # Output: [85, 92, 78, 95, 88]Kamu bahkan bisa mencampur tipe data berbeda dalam list yang sama, meskipun ini lebih jarang dipakai dalam praktik:
# List campuran tipe (lebih jarang, tapi valid)
mixed_data = ["Alice", 25, True, 3.14]
print(mixed_data) # Output: ['Alice', 25, True, 3.14]Sebuah list kosong(empty list) tidak berisi item apa pun dan dibuat hanya dengan kurung siku:
# List kosong
empty = []
print(empty) # Output: []
print(len(empty)) # Output: 0Fungsi len(), yang sudah kita gunakan dengan string, juga bekerja dengan list—fungsi ini mengembalikan jumlah item di dalam list.
14.1.2) Memahami Urutan List dan Posisi
List mempertahankan urutan saat kamu menambahkan item. Item pertama yang kamu masukkan tetap pertama, yang kedua tetap kedua, dan seterusnya. Urutan ini penting karena memungkinkan kamu mengakses item tertentu berdasarkan posisinya (juga disebut index).
Python menggunakan zero-based indexing: item pertama ada di posisi 0, item kedua di posisi 1, dan seterusnya. Ini mungkin terasa tidak biasa di awal, tapi ini adalah konvensi yang digunakan banyak bahasa pemrograman.
Mari lihat bagaimana ini bekerja dalam praktik:
students = ["Alice", "Bob", "Charlie", "Diana"]
# Mengakses siswa pertama (index 0)
first_student = students[0]
print(first_student) # Output: Alice
# Mengakses siswa ketiga (index 2)
third_student = students[2]
print(third_student) # Output: CharliePerhatikan bahwa untuk mendapatkan siswa ketiga, kita menggunakan index 2, bukan 3. Ini karena perhitungan dimulai dari 0.
14.1.3) Mengakses Elemen dengan Index Positif
Untuk mengakses elemen list, tulis nama list diikuti index dalam kurung siku: list_name[index]. Index harus berupa integer dalam rentang yang valid (0 sampai len(list) - 1).
Berikut contoh praktis bekerja dengan harga produk:
# Harga produk dalam dolar
prices = [19.99, 24.50, 15.75, 32.00, 8.99]
# Mengakses harga tertentu
first_price = prices[0]
last_index = len(prices) - 1 # Menghitung index valid terakhir
last_price = prices[last_index]
print(f"First product costs: ${first_price}") # Output: First product costs: $19.99
print(f"Last product costs: ${last_price}") # Output: Last product costs: $8.99Kenapa kita memakai len(prices) - 1 untuk index terakhir? Karena kalau sebuah list punya 5 item, index-nya adalah 0, 1, 2, 3, 4—index valid terakhir selalu satu lebih kecil dari panjangnya.
Kamu juga bisa memakai index dalam ekspresi dan perhitungan:
scores = [85, 92, 78, 95, 88]
# Menghitung rata-rata dari tiga skor pertama
first_three_average = (scores[0] + scores[1] + scores[2]) / 3
print(f"Average of first three: {first_three_average}") # Output: Average of first three: 85.014.1.4) Index Negatif: Menghitung dari Akhir
Python menyediakan fitur yang praktis: index negatif memungkinkan kamu mengakses item dari akhir list. Index -1 merujuk ke item terakhir, -2 ke item kedua dari terakhir, dan seterusnya.
students = ["Alice", "Bob", "Charlie", "Diana"]
# Mengakses dari akhir
last_student = students[-1]
second_to_last = students[-2]
print(last_student) # Output: Diana
print(second_to_last) # Output: CharlieIni sangat berguna saat kamu ingin item terakhir tapi tidak mau menghitung len(list) - 1:
prices = [19.99, 24.50, 15.75, 32.00, 8.99]
# Dua pendekatan ini setara
last_price_method1 = prices[len(prices) - 1]
last_price_method2 = prices[-1]
print(last_price_method1) # Output: 8.99
print(last_price_method2) # Output: 8.99Berikut cara index positif dan negatif memetakan item yang sama:
14.1.5) Apa yang Terjadi pada Index yang Tidak Valid
Jika kamu mencoba mengakses index yang tidak ada, Python akan memunculkan IndexError:
students = ["Alice", "Bob", "Charlie"]
# PERINGATAN: List ini punya index 0, 1, 2 (atau -3, -2, -1) - hanya untuk demonstrasi
# Mencoba mengakses index 3 menyebabkan error
# MASALAH: Index 3 tidak ada dalam list 3 item
# print(students[3]) # IndexError: list index out of rangeError ini adalah cara Python memberi tahu bahwa kamu meminta item yang tidak ada.
14.2) Indexing dan Slicing pada List
14.2.1) Memahami Dasar Slicing List
Sama seperti kita bisa melakukan slicing pada string (seperti yang kita pelajari di Bab 5), kita bisa melakukan slice pada list untuk mengekstrak bagiannya. Slice membuat list baru yang berisi subset elemen dari list asli. Sintaksnya adalah list[start:stop], di mana start adalah index tempat slice dimulai (inklusif) dan stop adalah tempat slice berakhir (eksklusif).
numbers = [10, 20, 30, 40, 50, 60, 70]
# Ambil elemen dari index 1 sampai (tapi tidak termasuk) index 4
subset = numbers[1:4]
print(subset) # Output: [20, 30, 40]Slice [1:4] mencakup index 1, 2, dan 3, tetapi berhenti sebelum index 4. Aturan "stop itu eksklusif" ini sama seperti pada slicing string.
Mari lihat contoh praktis dengan nama siswa:
students = ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank"]
# Ambil tiga siswa pertama
first_three = students[0:3]
print(first_three) # Output: ['Alice', 'Bob', 'Charlie']
# Ambil siswa dari index 2 sampai 4
middle_group = students[2:5]
print(middle_group) # Output: ['Charlie', 'Diana', 'Eve']14.2.2) Menghilangkan Start atau Stop dalam Slice
Kamu bisa menghilangkan index start untuk melakukan slicing dari awal, atau menghilangkan index stop untuk melakukan slicing sampai akhir:
scores = [85, 92, 78, 95, 88, 91, 87]
# Dari awal sampai index 3
first_few = scores[:3]
print(first_few) # Output: [85, 92, 78]
# Dari index 4 sampai akhir
last_few = scores[4:]
print(last_few) # Output: [88, 91, 87]
# Seluruh list (dari awal sampai akhir)
all_scores = scores[:]
print(all_scores) # Output: [85, 92, 78, 95, 88, 91, 87]Slice [:] membuat sebuah copy dari seluruh list. Ini berguna saat kamu ingin bekerja dengan duplikat tanpa memodifikasi yang asli—kita akan membahas ini lebih jauh di bagian 14.6.
14.2.3) Menggunakan Index Negatif dalam Slice
Index negatif bekerja dalam slice sama seperti saat mengakses elemen tunggal. Ini sangat berguna untuk mengambil item dari akhir:
students = ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank"]
# Ambil tiga siswa terakhir
last_three = students[-3:]
print(last_three) # Output: ['Diana', 'Eve', 'Frank']
# Ambil semua kecuali dua siswa terakhir
all_but_last_two = students[:-2]
print(all_but_last_two) # Output: ['Alice', 'Bob', 'Charlie', 'Diana']
# Ambil dari ketiga dari belakang sampai kedua dari belakang
middle_from_end = students[-3:-1]
print(middle_from_end) # Output: ['Diana', 'Eve']14.2.4) Slicing dengan Nilai Step
Kamu bisa menambahkan parameter ketiga untuk mengontrol step (berapa banyak index yang dilewati antar item). Sintaks lengkapnya adalah list[start:stop:step]:
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# Setiap angka kedua mulai dari index 0
evens = numbers[0:10:2]
print(evens) # Output: [0, 2, 4, 6, 8]
# Setiap angka ketiga mulai dari index 1
every_third = numbers[1:10:3]
print(every_third) # Output: [1, 4, 7]Kamu juga bisa memakai step negatif untuk membalik list:
numbers = [1, 2, 3, 4, 5]
# Membalik list
reversed_numbers = numbers[::-1]
print(reversed_numbers) # Output: [5, 4, 3, 2, 1]Slice [::-1] berarti "mulai dari akhir, ke awal, melangkah mundur 1." Ini adalah idiom Python yang umum untuk membalik sekuens.
14.2.5) Slice Tidak Pernah Menyebabkan IndexError
Berbeda dengan mengakses satu elemen, slicing sangat toleran. Jika kamu menentukan index di luar rentang list, Python akan menyesuaikannya agar pas:
numbers = [10, 20, 30, 40, 50]
# Meminta lebih banyak dari yang ada
extended_slice = numbers[2:100]
print(extended_slice) # Output: [30, 40, 50]
# Memulai melewati akhir
empty_slice = numbers[10:20]
print(empty_slice) # Output: []Perilaku ini berguna karena artinya kamu tidak perlu khawatir soal batas yang tepat saat slicing—Python menangani edge case dengan baik.
14.3) Memodifikasi List dan Method List yang Umum
14.3.1) List Itu Mutable: Mengubah Elemen
Berbeda dengan string, yang bersifat immutable, list bersifat mutable—kamu bisa mengubah isinya setelah dibuat. Kamu bisa memodifikasi elemen individual dengan menetapkan nilai baru ke index tertentu:
# Mulai dengan list harga
prices = [19.99, 24.50, 15.75, 32.00]
print(prices) # Output: [19.99, 24.5, 15.75, 32.0]
# Perbarui harga kedua (index 1)
prices[1] = 22.99
print(prices) # Output: [19.99, 22.99, 15.75, 32.0]
# Perbarui harga terakhir menggunakan indexing negatif
prices[-1] = 29.99
print(prices) # Output: [19.99, 22.99, 15.75, 29.99]Sifat mutable ini kuat—artinya kamu bisa memperbarui data di tempat tanpa membuat list baru. Namun, ini juga berarti kamu perlu berhati-hati terhadap perubahan yang tidak disengaja, yang akan kita bahas di bagian 14.6.
14.3.2) Menambahkan Elemen dengan append()
Method append() menambahkan satu item ke akhir list. Ini adalah salah satu operasi list yang paling sering digunakan:
# Mulai dengan keranjang belanja kosong
cart = []
print(cart) # Output: []
# Tambahkan item satu per satu
cart.append("Milk")
print(cart) # Output: ['Milk']
cart.append("Bread")
print(cart) # Output: ['Milk', 'Bread']
cart.append("Eggs")
print(cart) # Output: ['Milk', 'Bread', 'Eggs']Perhatikan bahwa append() memodifikasi list in place—method ini tidak mengembalikan list baru. Method ini mengembalikan None, jadi kamu tidak perlu menetapkan hasilnya:
scores = [85, 92, 78]
result = scores.append(95)
print(scores) # Output: [85, 92, 78, 95]
print(result) # Output: None14.3.3) Menyisipkan Elemen pada Posisi Tertentu dengan insert()
Sementara append() selalu menambah ke akhir, insert() memungkinkan kamu menambahkan item di posisi mana pun. Sintaksnya adalah list.insert(index, item):
students = ["Alice", "Charlie", "Diana"]
print(students) # Output: ['Alice', 'Charlie', 'Diana']
# Sisipkan "Bob" di index 1 (di antara Alice dan Charlie)
students.insert(1, "Bob")
print(students) # Output: ['Alice', 'Bob', 'Charlie', 'Diana']Saat kamu menyisipkan pada sebuah index, item yang saat itu ada di posisi tersebut (dan semua item setelahnya) bergeser ke kanan:
numbers = [10, 20, 30, 40]
print(numbers) # Output: [10, 20, 30, 40]
# Sisipkan 25 di index 2
numbers.insert(2, 25)
print(numbers) # Output: [10, 20, 25, 30, 40]Kamu bisa menyisipkan di awal dengan memakai index 0:
priorities = ["Medium", "Low"]
priorities.insert(0, "High")
print(priorities) # Output: ['High', 'Medium', 'Low']Jika kamu menentukan index melewati panjang list, insert() akan menambahkan item di akhir (seperti append()):
items = [1, 2, 3]
items.insert(100, 4)
print(items) # Output: [1, 2, 3, 4]14.3.4) Menghapus Elemen dengan remove()
Method remove() menghapus kemunculan pertama dari nilai tertentu dari list:
fruits = ["apple", "banana", "cherry", "banana", "date"]
print(fruits) # Output: ['apple', 'banana', 'cherry', 'banana', 'date']
# Hapus "banana" pertama
fruits.remove("banana")
print(fruits) # Output: ['apple', 'cherry', 'banana', 'date']Perhatikan bahwa hanya "banana" pertama yang dihapus—yang kedua masih ada. Jika kamu mencoba menghapus nilai yang tidak ada, Python memunculkan ValueError:
numbers = [10, 20, 30]
# PERINGATAN: Mencoba menghapus nilai yang tidak ada - hanya untuk demonstrasi
# MASALAH: 40 tidak ada di dalam list
# numbers.remove(40) # ValueError: list.remove(x): x not in listUntuk menghindari error ini, kamu bisa mengecek apakah itemnya ada sebelum menghapusnya:
cart = ["Milk", "Bread", "Eggs"]
item_to_remove = "Butter"
if item_to_remove in cart:
cart.remove(item_to_remove)
print(f"Removed {item_to_remove}")
else:
print(f"{item_to_remove} not in cart")
# Output: Butter not in cart14.3.5) Menghapus dan Mengembalikan Elemen dengan pop()
Method pop() menghapus item pada index tertentu dan mengembalikan item tersebut. Jika kamu tidak menentukan index, method ini menghapus dan mengembalikan item terakhir:
scores = [85, 92, 78, 95, 88]
# Hapus dan ambil skor terakhir
last_score = scores.pop()
print(f"Removed: {last_score}") # Output: Removed: 88
print(scores) # Output: [85, 92, 78, 95]
# Hapus dan ambil skor di index 1
second_score = scores.pop(1)
print(f"Removed: {second_score}") # Output: Removed: 92
print(scores) # Output: [85, 78, 95]Ini berguna saat kamu perlu memproses item dari list satu per satu:
tasks = ["Write code", "Test code", "Deploy code"]
while len(tasks) > 0:
current_task = tasks.pop(0) # Hapus dari awal
print(f"Working on: {current_task}")
# Output:
# Working on: Write code
# Working on: Test code
# Working on: Deploy code
print(tasks) # Output: []14.3.6) Memperluas List dengan extend()
Method extend() menambahkan semua item dari list lain (atau iterable apa pun) ke akhir list saat ini:
primary_colors = ["red", "blue", "yellow"]
secondary_colors = ["green", "orange", "purple"]
# Tambahkan semua warna sekunder ke warna primer
primary_colors.extend(secondary_colors)
print(primary_colors)
# Output: ['red', 'blue', 'yellow', 'green', 'orange', 'purple']Ini berbeda dari append(), yang akan menambahkan seluruh list sebagai satu elemen:
colors1 = ["red", "blue"]
colors2 = ["green", "orange"]
# Menggunakan append (menambahkan list sebagai satu elemen)
colors1.append(colors2)
print(colors1) # Output: ['red', 'blue', ['green', 'orange']]
# Menggunakan extend (menambahkan tiap elemen secara individual)
colors3 = ["red", "blue"]
colors3.extend(colors2)
print(colors3) # Output: ['red', 'blue', 'green', 'orange']14.3.7) Mengurutkan List dengan sort() dan sorted()
Python menyediakan dua cara untuk mengurutkan list. Method sort() mengurutkan list in place (memodifikasi yang asli):
scores = [78, 95, 85, 92, 88]
scores.sort()
print(scores) # Output: [78, 85, 88, 92, 95]Untuk mengurutkan secara menurun, gunakan parameter reverse:
scores = [78, 95, 85, 92, 88]
scores.sort(reverse=True)
print(scores) # Output: [95, 92, 88, 85, 78]Fungsi sorted() (yang akan kita bahas lebih jauh di Bab 38) membuat list baru yang sudah terurut tanpa memodifikasi yang asli:
original = [78, 95, 85, 92, 88]
sorted_scores = sorted(original)
print(original) # Output: [78, 95, 85, 92, 88]
print(sorted_scores) # Output: [78, 85, 88, 92, 95]Pengurutan juga bekerja dengan string, menggunakan urutan alfabet:
names = ["Charlie", "Alice", "Diana", "Bob"]
names.sort()
print(names) # Output: ['Alice', 'Bob', 'Charlie', 'Diana']14.3.8) Membalik List dengan reverse()
Method reverse() membalik list in place:
numbers = [1, 2, 3, 4, 5]
numbers.reverse()
print(numbers) # Output: [5, 4, 3, 2, 1]Ini berbeda dari mengurutkan secara menurun—reverse() hanya membalik urutan saat ini, apa pun urutannya:
mixed = [3, 1, 4, 1, 5]
mixed.reverse()
print(mixed) # Output: [5, 1, 4, 1, 3]Ingat bahwa kamu juga bisa membalik list menggunakan slicing: list[::-1]. Bedanya, slicing membuat list baru, sementara reverse() memodifikasi yang asli.
14.3.9) Menemukan Elemen dengan index() dan count()
Method index() mengembalikan posisi kemunculan pertama dari suatu nilai:
students = ["Alice", "Bob", "Charlie", "Diana", "Bob"]
# Cari "Charlie" ada di mana
position = students.index("Charlie")
print(f"Charlie is at index {position}") # Output: Charlie is at index 2
# Cari "Bob" yang pertama
bob_position = students.index("Bob")
print(f"Bob is at index {bob_position}") # Output: Bob is at index 1Jika nilainya tidak ada, index() memunculkan ValueError:
students = ["Alice", "Bob", "Charlie"]
# PERINGATAN: Mencoba mencari nilai yang tidak ada - hanya untuk demonstrasi
# MASALAH: 'Eve' tidak ada di dalam list
# position = students.index("Eve") # ValueError: 'Eve' is not in listMethod count() mengembalikan berapa kali suatu nilai muncul:
numbers = [1, 2, 3, 2, 4, 2, 5]
twos = numbers.count(2)
print(f"The number 2 appears {twos} times") # Output: The number 2 appears 3 times
# count bisa mengembalikan 0 jika itemnya tidak ada
sixes = numbers.count(6)
print(f"The number 6 appears {sixes} times") # Output: The number 6 appears 0 times14.3.10) Mengosongkan Semua Elemen dengan clear()
Method clear() menghapus semua item dari sebuah list, sehingga list menjadi kosong:
cart = ["Milk", "Bread", "Eggs", "Butter"]
print(cart) # Output: ['Milk', 'Bread', 'Eggs', 'Butter']
cart.clear()
print(cart) # Output: []
print(len(cart)) # Output: 0Ini setara dengan menetapkan list kosong, tetapi clear() lebih eksplisit soal maksudnya.
14.4) Menghapus Elemen List dengan del
14.4.1) Menggunakan del untuk Menghapus Elemen berdasarkan Index
Statement del bisa menghapus elemen list pada index tertentu:
students = ["Alice", "Bob", "Charlie", "Diana", "Eve"]
print(students) # Output: ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve']
# Hapus elemen pada index 2
del students[2]
print(students) # Output: ['Alice', 'Bob', 'Diana', 'Eve']Berbeda dengan pop(), del tidak mengembalikan nilai yang dihapus—ia hanya menghapusnya. Ini berguna saat kamu ingin menghapus item tapi tidak perlu memakainya:
scores = [85, 92, 78, 95, 88]
# Hapus skor terendah (di index 2)
del scores[2]
print(scores) # Output: [85, 92, 95, 88]Kamu juga bisa memakai index negatif dengan del:
tasks = ["Task 1", "Task 2", "Task 3", "Task 4"]
# Hapus task terakhir
del tasks[-1]
print(tasks) # Output: ['Task 1', 'Task 2', 'Task 3']14.4.2) Menghapus Slice dengan del
Statement del bisa menghapus seluruh slice sekaligus:
numbers = [10, 20, 30, 40, 50, 60, 70]
print(numbers) # Output: [10, 20, 30, 40, 50, 60, 70]
# Hapus elemen dari index 2 sampai 4 (index 2, 3, 4)
del numbers[2:5]
print(numbers) # Output: [10, 20, 60, 70]Ini sangat berguna untuk menghapus rentang elemen:
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Hapus tiga elemen pertama
del data[:3]
print(data) # Output: [4, 5, 6, 7, 8, 9, 10]
# Hapus dua elemen terakhir
del data[-2:]
print(data) # Output: [4, 5, 6, 7, 8]Kamu bahkan bisa menghapus setiap elemen selang-seling menggunakan step slicing:
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# Hapus setiap elemen kedua
del numbers[::2]
print(numbers) # Output: [1, 3, 5, 7, 9]14.4.3) Membandingkan del, remove(), dan pop()
Mari perjelas kapan harus memakai tiap metode penghapusan:
# Contoh list untuk perbandingan
items = ["apple", "banana", "cherry", "date", "elderberry"]
# Gunakan remove() saat kamu tahu NILAI yang akan dihapus
items_copy1 = items.copy()
items_copy1.remove("cherry") # Menghapus "cherry" pertama
print(items_copy1) # Output: ['apple', 'banana', 'date', 'elderberry']
# Gunakan pop() saat kamu tahu INDEX dan butuh nilainya
items_copy2 = items.copy()
removed_item = items_copy2.pop(2) # Menghapus dan mengembalikan item di index 2
print(f"Removed: {removed_item}") # Output: Removed: cherry
print(items_copy2) # Output: ['apple', 'banana', 'date', 'elderberry']
# Gunakan del saat kamu tahu INDEX tapi tidak butuh nilainya
items_copy3 = items.copy()
del items_copy3[2] # Hanya menghapus item di index 2
print(items_copy3) # Output: ['apple', 'banana', 'date', 'elderberry']14.5) Mengiterasi List dengan for Loop
14.5.1) Iterasi List Dasar
Salah satu operasi paling umum dengan list adalah memproses setiap item secara berurutan. for loop (yang kita pelajari di Bab 12) sangat cocok untuk ini:
students = ["Alice", "Bob", "Charlie", "Diana"]
# Memproses setiap siswa
for student in students:
print(f"Hello, {student}!")
# Output:
# Hello, Alice!
# Hello, Bob!
# Hello, Charlie!
# Hello, Diana!Variabel loop (student dalam kasus ini) akan mengambil setiap nilai dari list, satu per satu, sesuai urutan. Kamu bisa menamai variabel ini dengan apa pun yang bermakna:
scores = [85, 92, 78, 95, 88]
# Menghitung dan menampilkan nilai huruf untuk tiap skor
for score in scores:
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
else:
grade = "C"
print(f"Score {score} is a {grade}")
# Output:
# Score 85 is a B
# Score 92 is a A
# Score 78 is a C
# Score 95 is a A
# Score 88 is a B14.5.2) Memproses Item yang Berkorespondensi dari Banyak List
Terkadang kamu perlu bekerja dengan data terkait yang disimpan dalam list terpisah. Kita akan mempelajari fungsi zip() secara detail di Bab 38, tapi berikut pratinjau singkat tentang bagaimana zip() bisa membantu memproses item yang berkorespondensi:
# Kita akan belajar tentang zip() di Bab 38, tapi untuk sekarang, ini contoh sederhana
students = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]
# Memproses pasangan yang berkorespondensi
for student, score in zip(students, scores):
print(f"{student} scored {score}")
# Output:
# Alice scored 85
# Bob scored 92
# Charlie scored 78Fungsi zip() memasangkan elemen dari beberapa list, yang berguna saat kamu punya data terkait di list terpisah. Kita akan mengeksplor ini dan alat iterasi lain secara mendalam di Bab 38.
14.6) Menyalin List dan Menghindari Referensi Bersama
14.6.1) Memahami Referensi List
Saat kamu menetapkan list ke sebuah variabel, Python tidak membuat salinan list—Python membuat sebuah referensi(reference) ke objek list yang sama di memori. Ini berarti beberapa variabel bisa merujuk ke list yang sama:
original = [1, 2, 3]
reference = original # Kedua variabel menunjuk ke list yang SAMA
# Memodifikasi lewat satu variabel memengaruhi yang lain
reference.append(4)
print(original) # Output: [1, 2, 3, 4]
print(reference) # Output: [1, 2, 3, 4]Perilaku ini bisa mengejutkan jika kamu berharap reference adalah salinan yang mandiri. Mari lihat kenapa ini penting:
# Skenario: Kamu ingin melacak perubahan pada keranjang belanja
cart = ["Milk", "Bread"]
backup = cart # Mencoba menyimpan kondisi awal
# Tambahkan item lagi
cart.append("Eggs")
cart.append("Butter")
# Cek "backup"
print(backup) # Output: ['Milk', 'Bread', 'Eggs', 'Butter']Backup ikut berubah! Ini karena backup dan cart adalah dua nama untuk objek list yang sama.
14.6.2) Membuat Salinan Independen dengan Slicing
Untuk membuat salinan mandiri yang sebenarnya, gunakan slicing dengan [:]:
original = [1, 2, 3]
copy = original[:] # Membuat list BARU dengan isi yang sama
# Memodifikasi copy tidak memengaruhi original
copy.append(4)
print(original) # Output: [1, 2, 3]
print(copy) # Output: [1, 2, 3, 4]Sekarang mari perbaiki contoh keranjang belanja kita:
cart = ["Milk", "Bread"]
backup = cart[:] # Buat salinan mandiri
# Tambahkan item lagi ke cart
cart.append("Eggs")
cart.append("Butter")
# Backup tetap tidak berubah
print(cart) # Output: ['Milk', 'Bread', 'Eggs', 'Butter']
print(backup) # Output: ['Milk', 'Bread']14.6.3) Membuat Salinan dengan Method copy()
List juga punya method copy() yang melakukan hal yang sama seperti [:]:
original = [10, 20, 30]
copy = original.copy()
copy.append(40)
print(original) # Output: [10, 20, 30]
print(copy) # Output: [10, 20, 30, 40]Baik [:] maupun copy() membuat shallow copy, yang akan kita bahas berikutnya.
14.6.4) Keterbatasan Shallow Copy
Baik [:] maupun copy() membuat shallow copy. Artinya, mereka menyalin struktur list, tapi jika list berisi objek mutable lain (seperti list lain), objek bagian dalam itu masih dibagikan:
# List yang berisi list
original = [[1, 2], [3, 4], [5, 6]]
copy = original[:]
# Memodifikasi struktur list luar bersifat independen
copy.append([7, 8])
print(original) # Output: [[1, 2], [3, 4], [5, 6]]
print(copy) # Output: [[1, 2], [3, 4], [5, 6], [7, 8]]
# Tapi memodifikasi list bagian dalam memengaruhi keduanya!
copy[0].append(99)
print(original) # Output: [[1, 2, 99], [3, 4], [5, 6]]
print(copy) # Output: [[1, 2, 99], [3, 4], [5, 6], [7, 8]]Kenapa ini terjadi? Karena shallow copy membuat list luar yang baru, tapi list bagian dalamnya masih merupakan referensi yang sama:
Untuk struktur bersarang, kamu akan membutuhkan deep copy, yang akan kita pelajari saat mengeksplor modul copy di bab-bab selanjutnya. Untuk saat ini, sadari bahwa shallow copy bekerja sempurna untuk list berisi item immutable (angka, string, tuple), tapi perlu kehati-hatian untuk struktur mutable bersarang.
14.6.5) Kapan Referensi Bersama Itu Berguna
Terkadang kamu ingin beberapa variabel merujuk ke list yang sama. Ini berguna saat kamu perlu memodifikasi list dari bagian kode yang berbeda:
# Fungsi yang memodifikasi list secara in place
def add_bonus_points(scores, bonus):
for i in range(len(scores)):
scores[i] = scores[i] + bonus
# List asli dimodifikasi
student_scores = [85, 92, 78]
add_bonus_points(student_scores, 5)
print(student_scores) # Output: [90, 97, 83]Ini bekerja karena fungsi menerima referensi ke list asli, bukan salinannya. Kita akan mengeksplor ini lebih jauh ketika mempelajari fungsi(function) secara detail di Bagian V.
14.7) Menggunakan enumerate() Saat Melakukan Loop pada List
14.7.1) Kebutuhan untuk Mendapatkan Index dan Nilai
Terkadang saat mengiterasi list, kamu butuh index dan nilai sekaligus. Salah satu pendekatan adalah memakai range(len(list)):
students = ["Alice", "Bob", "Charlie", "Diana"]
for i in range(len(students)):
print(f"Student {i}: {students[i]}")
# Output:
# Student 0: Alice
# Student 1: Bob
# Student 2: Charlie
# Student 3: DianaIni bekerja, tapi tidak terlalu elegan. Kamu harus memakai students[i] untuk mengakses setiap nilai, yang kurang mudah dibaca dibanding mengiterasi langsung nilainya.
14.7.2) Menggunakan enumerate() untuk Kode yang Lebih Bersih
Fungsi enumerate() memberikan solusi yang lebih baik. Fungsi ini mengembalikan index dan nilai untuk setiap item:
students = ["Alice", "Bob", "Charlie", "Diana"]
for index, student in enumerate(students):
print(f"Student {index}: {student}")
# Output:
# Student 0: Alice
# Student 1: Bob
# Student 2: Charlie
# Student 3: DianaSintaks for index, value in enumerate(list) melakukan unpacking setiap pasangan yang dihasilkan enumerate(). Ini jauh lebih mudah dibaca daripada memakai range(len()).
14.7.3) Memulai enumerate() dari Angka yang Berbeda
Secara default, enumerate() mulai menghitung dari 0. Kamu bisa menentukan angka awal yang berbeda dengan parameter start:
students = ["Alice", "Bob", "Charlie", "Diana"]
# Mulai menghitung dari 1, bukan 0
for position, student in enumerate(students, start=1):
print(f"Position {position}: {student}")
# Output:
# Position 1: Alice
# Position 2: Bob
# Position 3: Charlie
# Position 4: DianaIni berguna saat kamu ingin menampilkan penomoran yang ramah manusia (mulai dari 1) alih-alih indexing yang ramah programmer (mulai dari 0).
Contoh Praktis dengan enumerate()
Berikut contoh praktis menampilkan menu 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. Quit14.7.4) Memodifikasi List dengan enumerate()
Kamu bisa memakai enumerate() saat perlu memodifikasi elemen list berdasarkan posisinya:
# Tambahkan bonus berbasis posisi ke skor
scores = [85, 92, 78, 95, 88]
for index, score in enumerate(scores):
# Siswa pertama mendapat 5 poin bonus, siswa kedua mendapat 4, dan seterusnya
bonus = 5 - index
if bonus > 0:
scores[index] = score + bonus
print(scores) # Output: [90, 96, 81, 97, 89]14.8) Pola Umum List: Mencari, Memfilter, dan Mengagregasi Data
14.8.1) Mencari Item dalam List
Salah satu tugas paling umum adalah mengecek apakah sebuah list berisi item tertentu. Operator in (yang kita pelajari di Bab 7) membuat ini jadi mudah:
students = ["Alice", "Bob", "Charlie", "Diana"]
# Cek apakah seorang siswa ada di dalam list
if "Charlie" in students:
print("Charlie is enrolled") # Output: Charlie is enrolled
if "Eve" not in students:
print("Eve is not enrolled") # Output: Eve is not enrolledUntuk menemukan posisi sebuah item, gunakan method index() (dibahas di bagian 14.3.9), tapi ingat untuk mengecek apakah itemnya ada terlebih dahulu:
scores = [85, 92, 78, 95, 88]
target_score = 95
if target_score in scores:
position = scores.index(target_score)
print(f"Score {target_score} found at index {position}")
# Output: Score 95 found at index 3
else:
print(f"Score {target_score} not found")14.8.2) Menemukan Nilai Maksimum dan Minimum
Fungsi bawaan Python max() dan min() bekerja dengan list:
scores = [85, 92, 78, 95, 88, 91, 76]
highest_score = max(scores)
lowest_score = min(scores)
print(f"Highest score: {highest_score}") # Output: Highest score: 95
print(f"Lowest score: {lowest_score}") # Output: Lowest score: 7614.8.3) Menghitung Agregat: Jumlah, Rata-rata, dan Jumlah Item
Menghitung total dan rata-rata adalah operasi list yang fundamental:
scores = [85, 92, 78, 95, 88, 91, 76, 89]
# Hitung total dan rata-rata
total = sum(scores)
count = len(scores)
average = total / count
print(f"Total: {total}") # Output: Total: 694
print(f"Count: {count}") # Output: Count: 8
print(f"Average: {average:.2f}") # Output: Average: 86.75Berikut contoh praktis menghitung total keranjang belanja:
cart_items = ["Milk", "Bread", "Eggs", "Butter", "Cheese"]
prices = [3.99, 2.49, 4.99, 5.49, 6.99]
# Hitung total biaya
total_cost = sum(prices)
item_count = len(cart_items)
print(f"Items in cart: {item_count}")
print(f"Total cost: ${total_cost:.2f}")
# Output:
# Items in cart: 5
# Total cost: $23.9514.9) Mutability List dan Truthiness dalam Kondisi
14.9.1) Memahami Mutability List dalam Praktik
Kita sudah melihat sepanjang bab ini bahwa list bersifat mutable—list bisa diubah setelah dibuat. Mutability inilah yang membuat list begitu kuat untuk menyimpan dan memanipulasi kumpulan data. Mari kita rangkum pemahaman kita dengan contoh yang komprehensif:
# Mulai dengan list task kosong
tasks = []
print(f"Initial tasks: {tasks}") # Output: Initial tasks: []
# Tambahkan task
tasks.append("Write code")
tasks.append("Test code")
tasks.append("Deploy code")
print(f"After adding: {tasks}")
# Output: After adding: ['Write code', 'Test code', 'Deploy code']
# Sisipkan task mendesak di awal
tasks.insert(0, "Review requirements")
print(f"After inserting: {tasks}")
# Output: After inserting: ['Review requirements', 'Write code', 'Test code', 'Deploy code']
# Selesaikan dan hapus task pertama
completed = tasks.pop(0)
print(f"Completed: {completed}") # Output: Completed: Review requirements
print(f"Remaining: {tasks}")
# Output: Remaining: ['Write code', 'Test code', 'Deploy code']
# Modifikasi sebuah task
tasks[1] = "Test code thoroughly"
print(f"After modifying: {tasks}")
# Output: After modifying: ['Write code', 'Test code thoroughly', 'Deploy code']14.9.2) Mutability vs Immutability: List vs String
Penting untuk memahami perbedaan antara list yang mutable dan string yang immutable. Pada string, operasi membuat string baru alih-alih memodifikasi yang asli:
# String bersifat immutable
text = "hello"
text.upper() # Membuat string baru, tidak mengubah yang asli
print(text) # Output: hello (tidak berubah)
# Untuk "mengubah" string, kamu harus menetapkan ulang
text = text.upper()
print(text) # Output: HELLO
# List bersifat mutable
numbers = [1, 2, 3]
numbers.append(4) # Memodifikasi list secara in place
print(numbers) # Output: [1, 2, 3, 4] (berubah)Perbedaan ini memengaruhi cara kamu bekerja dengan tipe-tipe ini:
# Operasi string membutuhkan penetapan ulang
name = "alice"
name = name.capitalize() # Harus menetapkan ulang agar terlihat perubahannya
print(name) # Output: Alice
# Operasi list memodifikasi di tempat
scores = [85, 92, 78]
scores.append(95) # Tidak perlu penetapan ulang
print(scores) # Output: [85, 92, 78, 95]14.9.3) Menggunakan List dalam Konteks Boolean
List memiliki truthiness: list kosong dianggap False, dan list yang tidak kosong dianggap True. Ini berguna dalam statement kondisional:
# List kosong bersifat falsy
empty_cart = []
if empty_cart:
print("Cart has items")
else:
print("Cart is empty") # Output: Cart is empty
# List tidak kosong bersifat truthy
cart_with_items = ["Milk", "Bread"]
if cart_with_items:
print("Cart has items") # Output: Cart has itemsPola ini umum digunakan untuk mengecek apakah sebuah list punya elemen sebelum diproses:
students = ["Alice", "Bob", "Charlie"]
if students:
print(f"We have {len(students)} students")
for student in students:
print(f" - {student}")
else:
print("No students enrolled")
# Output:
# We have 3 students
# - Alice
# - Bob
# - Charlie14.9.4) Pola Praktis: Memproses Sampai Kosong
Truthiness dari list memungkinkan pola yang berguna untuk memproses item sampai sebuah list kosong:
# Memproses task sampai tidak ada yang tersisa
tasks = ["Task 1", "Task 2", "Task 3"]
while tasks: # Lanjutkan selama list tidak kosong
current_task = tasks.pop(0)
print(f"Processing: {current_task}")
print("All tasks completed!")
# Output:
# Processing: Task 1
# Processing: Task 2
# Processing: Task 3
# All tasks completed!14.9.5) Mengecek List Kosong: Eksplisit vs Implisit
Ada dua cara untuk mengecek apakah list kosong:
items = []
# Cek implisit (Pythonic)
if not items:
print("List is empty") # Output: List is empty
# Cek eksplisit (juga valid)
if len(items) == 0:
print("List is empty") # Output: List is emptyCek implisit (if not items:) umumnya lebih disukai di Python karena lebih ringkas dan bekerja untuk tipe koleksi apa pun. Namun, kedua pendekatan benar dan kamu akan melihat keduanya di kode nyata.
14.9.6) Mutability dan Perilaku Fungsi
Saat kamu mengoper sebuah list ke sebuah fungsi (yang akan kita eksplor secara detail di Bagian V), fungsi menerima referensi ke objek list yang sama. Ini berarti fungsi bisa memodifikasi list aslinya:
def add_item(shopping_list, item):
shopping_list.append(item)
print(f"Added {item}")
# List asli dimodifikasi
cart = ["Milk", "Bread"]
print(f"Before: {cart}") # Output: Before: ['Milk', 'Bread']
add_item(cart, "Eggs") # Output: Added Eggs
print(f"After: {cart}") # Output: After: ['Milk', 'Bread', 'Eggs']Perilaku ini berbeda dengan tipe immutable seperti string dan angka, di mana nilai asli tidak bisa diubah oleh fungsi. Memahami perbedaan ini sangat penting untuk menulis program yang benar.
List adalah salah satu struktur data Python yang paling fundamental dan serbaguna. List menyediakan koleksi yang terurut dan mutable yang bisa bertambah dan berkurang sesuai kebutuhan, sehingga sangat cocok untuk menyimpan dan memproses sekuens data terkait. Kamu sudah belajar cara membuat list, mengakses elemennya lewat indexing dan slicing, memodifikasinya dengan berbagai method, mengiterasi dengan efisien, dan memahami sifat mutable-nya.
Pola yang kita eksplor—mencari, memfilter, mengagregasi, dan mentransformasikan data—menjadi dasar untuk bekerja dengan koleksi di Python. Saat kamu lanjut belajar, kamu akan menemukan cara yang lebih kuat untuk bekerja dengan list, termasuk list comprehension (Bab 35) dan teknik iterasi lanjutan (Bab 36-37). Tapi dasar-dasar yang kamu kuasai di bab ini akan sangat berguna sepanjang perjalanan pemrograman Python-mu.