Mengubah setiap harga menjadi harga bertype pajak, menyaring produk mahal, menjumlahkan subtotal — pekerjaan mengolah koleksi seperti ini muncul di hampir semua program. Cara manual dengan loop for dan append selalu berhasil, tetapi tiga tool bawaan Python menyediakan bentuk yang lebih deklaratif: map untuk mentransformasi, filter untuk menyaring, dan reduce untuk meringkas. Memahami ketiganya juga membantu membaca kode library modern yang memakai gaya fungsional.

map: Satu Function, Banyak Elemen #

map(function, iterable) menerapkan satu function ke setiap elemen. Kuncinya: map tidak langsung membangun list — map mengembalikan object lazy iterator yang baru menghitung saat elemennya diminta:

python
kuadrat = map(lambda x: x ** 2, [1, 2, 3, 4])
print(type(kuadrat).__name__)

print(next(kuadrat))
print(list(kuadrat))

Output yang Dihasilkan:

text
map
1
[4, 9, 16]

Mari kita telaah apa yang terjadi pada baris-baris kode di atas:

  1. Baris 1 (kuadrat = map(...)): pemanggilan map belum menyentuh satu elemen pun — yang dibuat hanyalah object map yang menyimpan rencana transformasi.
  2. Baris 2 (print(type(...))): tipe hasilnya adalah map, bukan list.
  3. Baris 4 (next(kuadrat)): next memaksa elemen pertama dihitung — 1 ** 2 menghasilkan 1. Elemen tersebut kini habis dikonsumsi.
  4. Baris 5 (list(kuadrat)): list memaksa sisa elemen — hasilnya [4, 9, 16], hanya tiga nilai, karena elemen pertama sudah terpakai.

Perilaku lazy ini sama dengan generator yang kita pelajari pada Chapter Generator Expressions dan Lazy Evaluation: hemat memori untuk data besar, tetapi iterator hanya bisa dikonsumsi sekali.

map juga menerima lebih dari satu iterable. Function diterapkan paralel per posisi, dan pemrosesan berhenti di iterable terpendek:

python
harga = [15000, 22500, 8000]
jumlah = [2, 1, 3]

subtotal = list(map(lambda h, j: h * j, harga, jumlah))
print(subtotal)

Output yang Dihasilkan:

text
[30000, 22500, 24000]

Lambda (h, j) menerima satu harga dan satu jumlah pada posisi yang sama, lalu mengalikannya — pola yang sejalan dengan perilaku zip pada Chapter zip().

filter: Menyaring Elemen #

filter(function, iterable) hanya meloloskan elemen yang membuat function mengembalikan nilai truthy:

python
produk = [("kopi", 45000), ("gula", 12000), ("teh", 25000), ("susu", 32000)]

murah = list(filter(lambda p: p[1] < 30000, produk))
print(murah)

Output yang Dihasilkan:

text
[('gula', 12000), ('teh', 25000)]

Lambda membaca harga di p[1]; hanya produk di bawah 30000 lolos. Sama seperti map, hasil filter adalah iterator lazy yang perlu dimaterialisasi dengan list.

reduce: Meringkas Banyak menjadi Satu #

map dan filter menjaga jumlah elemen. reduce mengecilkannya menjadi satu nilai dengan menggulung elemen satu per satu ke sebuah accumulator. Di Python 2 reduce adalah built-in; di Python 3 function ini pindah ke module functools — keputusan yang mencerminkan bahwa loop eksplisit lebih sering menjadi pilihan utama.

Contoh: menerapkan dua potongan harga secara berurutan:

python
from functools import reduce

def terapkan_potongan(harga, potongan):
    return round(harga * (1 - potongan))

harga_awal = 200000
potongan_berurutan = [0.10, 0.05]

harga_akhir = reduce(terapkan_potongan, potongan_berurutan, harga_awal)
print(harga_akhir)

Output yang Dihasilkan:

text
171000

Bagaimana reduce sampai ke angka itu? Berikut jejaknya langkah demi langkah:

Langkahacc (harga)x (potongan)round(acc * (1 - x))
12000000.10180000
21800000.05171000

Argument ketiga harga_awal mengisi nilai awal acc. Tanpa argument tersebut, reduce memakai elemen pertama iterable sebagai titik awal. Setiap langkah memanggil terapkan_potongan(acc, x) — perhatikan urutan parameternya: accumulator selalu menjadi parameter pertama.

map dan filter vs Comprehension #

Untuk transformasi dan penyaringan sederhana, komunitas Python justru lebih memilih comprehension yang kita pelajari pada Chapter List Comprehensions:

python
harga = [15000, 22500, 8000]

dengan_map = list(map(lambda x: x * 2, harga))
dengan_comprehension = [x * 2 for x in harga]

print(dengan_map)
print(dengan_comprehension)
print(dengan_map == dengan_comprehension)

Output yang Dihasilkan:

text
[30000, 45000, 16000]
[30000, 45000, 16000]
True

Keduanya identik secara hasil. Perbandingan selera keterbacaannya:

Aspekmap/filter + lambdaComprehension
KeterbacaanNama function anonim, dibaca dari dalam ke luarNyaris seperti kalimat bahasa Inggris
Kombinasi transform + saringmap(f, filter(p, data)) bersarang dua lapisSatu ekspresi: [f(x) for x in data if p(x)]
Posisi di idiom PythonSekunder untuk kasus sederhanaIdiom utama
Unggul saatFunction sudah ada bernama, mis. map(str.strip, baris)Hampir semua kasus sehari-hari

Kesimpulan praktisnya: pilih comprehension untuk logika sederhana; sisakan map dan filter untuk saat function transformasi sudah tersedia sebagai nama, dan reduce untuk penggulungan yang benar-benar membutuhkannya.