Lambda & Higher-Order Functions — Python

Lambda & Higher-Order Functions Lambda Expression Lambda adalah fungsi anonim satu baris: # Fungsi biasa def kuadrat(x): return x ** 2 # Sama dengan lambda…

Lambda adalah fungsi kecil tanpa nama, ditulis dalam satu ekspresi. Biasanya dia gak berdiri sendiri, tapi langsung dikirim ke fungsi lain yang butuh "aturan", misalnya aturan mengurutkan. Bayangin Pak Darto minta asistennya merapikan papan menu. Dia gak menulis kartu resep lengkap untuk itu. Cukup tempel catatan kecil: "urutkan menurut harga". Catatan sekali pakai itu lambda-nya.

🧪 Tebakan cepat: print(map(lambda m: m[0], menu)) mencetak daftar nama menu, atau yang lain? Tebak dulu, jawabannya ada di bagian "map() dan filter()".

Lambda: fungsi satu baris tanpa nama

def kuadrat(x):
    return x ** 2

kuadrat = lambda x: x ** 2   # sama persis dengan def di atas
print(kuadrat(4))            # 16

sorted() dengan key

Menu warung disimpan sebagai list berisi pasangan nama dan harga. Tiap pasangan adalah tuple, beberapa nilai di dalam kurung biasa. m[0] mengambil isi pertamanya (nama), m[1] isi keduanya (harga).

menu = [("kopi susu", 15000), ("teh manis", 5000), ("roti bakar", 12000), ("es jeruk", 8000)]

print(sorted(menu, key=lambda m: m[1]))
print(sorted(menu, key=lambda m: m[1], reverse=True))
[('teh manis', 5000), ('es jeruk', 8000), ('roti bakar', 12000), ('kopi susu', 15000)]
[('kopi susu', 15000), ('roti bakar', 12000), ('es jeruk', 8000), ('teh manis', 5000)]

Fungsi yang menerima fungsi lain sebagai argumen, seperti sorted, max, map, dan filter, disebut higher-order function.

map() dan filter()

print(list(map(lambda m: m[0], menu)))
print(list(filter(lambda m: m[1] < 10000, menu)))
print(map(lambda m: m[0], menu))
['kopi susu', 'teh manis', 'roti bakar', 'es jeruk']
[('teh manis', 5000), ('es jeruk', 8000)]
<map object at 0x10033d060>

Baris ketiga bukan daftar nama. map dan filter di Python 3 gak langsung menghitung semuanya. Mereka memberi iterator: antrean hasil yang baru dihitung saat diminta. print cuma menulis objeknya, <map object at 0x...>, dan angka di belakang 0x (alamat memorinya) beda tiap kali program jalan. Itu jawaban tebakannya. list(...) yang meminta semua hasilnya sekaligus.

Iterator cuma bisa dibaca sekali:

murah = filter(lambda m: m[1] < 10000, menu)
print(list(murah))   # [('teh manis', 5000), ('es jeruk', 8000)]
print(list(murah))   # [], sudah habis

map dan filter bisa disambung. Nama menu yang harganya di bawah Rp10.000:

murah = filter(lambda m: m[1] < 10000, menu)
nama = list(map(lambda m: m[0], murah))
print(nama)   # ['teh manis', 'es jeruk']

Saring dulu dengan filter, baru ubah tiap sisanya dengan map. Syarat lain tinggal diganti, misalnya x % 2 != 0 untuk angka ganjil, atau x ** 2 untuk mengkuadratkan.

Kapan lambda, kapan def

📌 reduce dan comprehension

reduce dari modul functools meringkas semua isi jadi satu nilai, dua-dua sekaligus:

from functools import reduce

harga = [15000, 5000, 12000, 8000]
print(reduce(lambda a, b: a + b, harga, 0))   # 40000

Untuk menjumlah, sum(harga) lebih jelas. Banyak orang juga lebih suka list comprehension daripada map dan filter: [m[0] for m in menu if m[1] < 10000] memberi ['teh manis', 'es jeruk'] juga. Comprehension dibahas di pelajarannya sendiri.

⚠️ Jebakan yang sering ketemu

TL;DR: lambda x: ekspresi adalah fungsi tanpa nama yang otomatis mengembalikan ekspresinya ((lambda x: x ** 2)(4) hasilnya 16), tanpa return. Tempatnya sebagai argumen ke higher-order function. sorted(menu, key=lambda m: m[1]) mengurutkan menurut harga, reverse=True membaliknya, dan menu gak berubah. map mengubah tiap isi, filter menyimpan yang True, dan keduanya memberi iterator: print menulis <map object at 0x...>, jadi bungkus dengan list(...), dan ingat iterator cuma bisa dibaca sekali. Logika panjang atau dipakai berulang? def.

Yang akan kamu pelajari