Menangani Error dan Edge Case dalam map()
Meskipun map() sangat efisien, fungsi ini dapat menyebabkan perilaku tak terduga atau error jika tidak digunakan dengan hati-hati. Kita perlu memahami jebakan umum ini, terutama terkait mutabilitas dan tipe. Mari lihat beberapa edge case dan cara menangani error.
Menangani state yang mutable
Kesalahan umum adalah menggunakan map() dengan fungsi yang memutasi (mengubah di tempat) inputnya, terutama ketika input tersebut adalah objek mutable seperti list atau dictionary.
Fungsi map() dirancang untuk transformasi, bukan untuk efek samping in-place. Meskipun secara teknis memungkinkan memutasi objek di dalam fungsi yang diteruskan ke map(), ini dianggap praktik buruk karena beberapa alasan:
-
Ini membingungkan dan kurang Pythonic (bertentangan dengan gaya pemrograman fungsional).
-
Karena
map()bersifat lazy di Python 3, mutasi tidak terjadi sampai objek map dikonsumsi (mis., dengan konversi ke list atau iterasi). -
Jauh kurang eksplisit dibanding
forloop sederhana.
Efek samping map()
Menggunakan map() untuk efek samping dianggap praktik buruk. Mari lihat alasannya:
def add_bonus(employee_dict):
# This function MUTATES the dictionary
employee_dict['salary'] *= 1.10
return employee_dict
employees = [
{'name': 'Alice', 'salary': 100000},
{'name': 'Bob', 'salary': 120000}
]
map(add_bonus, employees)
print(employees)
[{'name': 'Alice', 'salary': 100000}, {'name': 'Bob', 'salary': 120000}]
Kita bisa melihat outputnya; belum ada yang berubah, karena map() bersifat lazy. Pembaruan hanya terjadi saat Anda membungkusnya dengan list():
list(map(add_bonus, employees))
print(employees)
[{'name': 'Alice', 'salary': 110000.00000000001}, {'name': 'Bob', 'salary': 132000.0}]
Perilaku ini membingungkan dan dapat menyebabkan kejutan yang tidak menyenangkan. Jika tujuan Anda adalah memutasi in-place, for loop sederhana jauh lebih jelas, seperti di bawah:
for emp in employees:
emp['salary'] *= 1.10
employees
[{'name': 'Alice', 'salary': 110000.00000000001},
{'name': 'Bob', 'salary': 132000.0}]
Praktik terbaik untuk menghindari error saat menggunakan map()
Untuk map(), ini berarti menggunakannya hanya untuk transformasi murni guna mengembalikan objek baru, bukan mengubah objek lama. Mari lihat contoh di atas menggunakan map():
def calculate_bonus(employee_dict):
new_record = employee_dict.copy() # Or use dict(employee_dict)
new_record['salary'] *= 1.10
return new_record
employees = [
{'name': 'Alice', 'salary': 100000},
{'name': 'Bob', 'salary': 120000}
]
updated_employees = list(map(calculate_bonus, employees))
print("--- Original ---")
print(employees) # The original data is safe
print("--- Updated ---")
print(updated_employees)
--- Original ---
[{'name': 'Alice', 'salary': 100000}, {'name': 'Bob', 'salary': 120000}]
--- Updated ---
[{'name': 'Alice', 'salary': 110000.0}, {'name': 'Bob', 'salary': 132000.0}]
Beberapa pedoman praktis:
-
Gunakan
map()saat Anda ingin mendapatkan data baru (fungsi murni, gaya immutable). -
Gunakan
forloop (atau list comprehension) saat Anda memang ingin memutasi in-place. -
Hindari mengandalkan efek samping dalam
map()karena menimbulkan masalah yang samar dan sulit dideteksi.
Keterbatasan tipe dan jebakan umum
Error paling umum dengan map() adalah pengecualian TypeError. Hampir selalu jatuh ke dalam salah satu dari tiga kategori berikut.
Fungsinya tidak callable
Saat Anda meneruskan sesuatu ke map() sebagai argumen pertama yang bukan fungsi, metode, atau lambda, Anda akan menerima TypeError.
my_list = [1, 2, 3]
message = "Not a function"
# This will fail
try:
list(map(message, my_list))
except TypeError as e:
print(e)
'str' object is not callable
Argumen tidak iterable
Hal yang sama terjadi ketika Anda meneruskan sesuatu sebagai argumen kedua (atau iterable berikutnya) yang tidak bisa dilintasi oleh Python, seperti sebuah angka tunggal atau boolean.
def square(x):
return x * x
# This will fail
try:
list(map(square, 12345))
except TypeError as e:
print(e)
'int' object is not iterable
Ketidakcocokan jumlah argumen saat menggunakan banyak iterable
Ketika Anda memberikan map() lebih dari satu iterable, fungsi ini mengambil satu item dari setiap iterable pada setiap pemanggilan. Fungsi Anda harus menerima tepat sebanyak itu argumen; jika tidak, akan memicu TypeError juga.
list_a = [1, 2, 3]
list_b = [4, 5, 6]
# Wrong: lambda only accepts one argument
try:
list(map(lambda x: x * x, list_a, list_b))
except TypeError as e:
print(e)
<lambda>() takes 1 positional argument but 2 were given
Untuk men-debug masalah ini:
-
Periksa argumen pertama: Pastikan itu benar-benar nama fungsi tanpa tanda kurung (seperti
square, bukansquare()), lambda, atau metode bawaan (sepertistr.strip)? -
Periksa argumen kedua: Pastikan itu benar-benar list, tuple, set, string, atau koleksi lain?
-
Periksa ketidakcocokan argumen: Jika menggunakan beberapa iterable, apakah fungsi Anda menerima jumlah argumen yang benar?
Mengoptimalkan Performa dengan map() di Python
Meskipun lazy evaluation pada map() sudah memberikan manfaat memori yang signifikan, Anda bisa lebih mengoptimalkan kecepatan dan efisiensinya. Strategi ini berguna saat bekerja dengan pipeline data yang kritis terhadap performa. Mari lihat beberapa strategi performa dan benchmark.
Praktik terbaik map()
Kita bisa meningkatkan keuntungan performa dari fungsi map() dengan menggunakan metode berikut:
Lebih suka fungsi bawaan
Sebisa mungkin, gunakan fungsi bawaan (seperti len(), str.strip(), str.upper()) langsung sebagai fungsi pemetaan alih-alih membungkusnya dalam lambda. Fungsi bawaan sangat dioptimalkan (sering diimplementasikan dalam C) dan hampir selalu lebih cepat daripada lambda atau fungsi Python buatan pengguna yang setara.
-
Lebih cepat:
map(str.upper, my_list) -
Lebih lambat:
map(lambda s: s.upper(), my_list)
Manfaatkan itertools
Modul itertools adalah sahabat Anda untuk iterasi berperforma tinggi. Fungsi seperti itertools.starmap() atau itertools.islice() dirancang untuk bekerja dengan objek map dan mempertahankan efisiensi memori saat melakukan pemotongan iterator secara lazy. Merangkai fungsi itertools sangat berguna dalam pemrosesan data.
Hindari konversi list yang tidak perlu
Ini aturan paling penting. Memanggil list(map(...)) memaksa seluruh operasi dieksekusi segera dan memuat semua hasil ke memori. Hindari konversi ini di dalam loop atau langkah perantara. Pertahankan data Anda sebagai iterator selama mungkin, dan hanya konversi ke list saat Anda benar-benar memerlukan koleksi final yang konkret.
Benchmark performa
Mari lihat dampak pilihan-pilihan ini menggunakan beberapa benchmark.
Saat Anda memanggil map(lambda x: len(x), data), Python harus memanggil fungsi lambda untuk setiap item, yang kemudian memanggil len() bawaan. Lapisan overhead pemanggilan fungsi ekstra ini akan terakumulasi.
Saat Anda menggunakan map(len, data), map() dapat langsung memanggil fungsi len() yang sangat dioptimalkan untuk setiap item.
Berikut benchmark sederhana menggunakan timeit:
import timeit
data = ['apple', 'banana', 'cherry'] * 100000
# Benchmark 1: Using lambda
time_lambda = timeit.timeit(
'list(map(lambda s: len(s), data))',
globals=globals(),
number=100
)
# Benchmark 2: Using built-in
time_builtin = timeit.timeit(
'list(map(len, data))',
globals=globals(),
number=100
)
print(f"Time with lambda: {time_lambda:.4f}s")
print(f"Time with built-in: {time_builtin:.4f}s")
# The built-in will be significantly faster
Time with lambda: 2.5304s
Time with built-in: 0.5363s
Benchmark kecepatan di atas memang memaksa konversi list(). Namun, manfaat performa utama dari map() adalah efisiensi memori. Pertimbangkan memproses berkas log 5GB baris demi baris.
-
List comprehension: Karena akan mencoba membaca seluruh berkas 5GB dan menyimpan jutaan hasil proses di RAM, ini kemungkinan memicu
MemoryError. -
Fungsi
map(): Membuat hanya objekmapkecil. Saat Anda melakukan iterasi di atasnya (mis.,for r in results:), ia membaca satu baris dari berkas, memprosesnya, menghasilkan hasilnya, lalu baru membaca baris berikutnya. Tidak ada saat pun lebih dari satu baris hasil ditahan di memori.
Perilaku pemuatan-lazy inilah yang membuat map() menjadi pilihan unggul untuk pemrosesan data skala besar, terutama dalam framework seperti PySpark, di mana data bahkan mungkin tidak berada pada satu mesin. Untuk pandangan cepat dan mendalam tentang alat data skala besar seperti PySpark, lihat lembar contekan PySpark.
map() vs. List Comprehension dan Alternatifnya
Tidak diragukan lagi, fungsi map() adalah alat yang kuat. Namun, ini bukan satu-satunya cara untuk menerapkan sebuah operasi ke seluruh iterable. Memilih alat yang tepat untuk pekerjaan—apakah map(), list comprehension, atau ekspresi generator—penting untuk menulis kode yang bersih, efisien, dan Pythonic.
Mari rangkum perbedaannya yang telah kita temukan sepanjang tutorial:
|
Metode |
Contoh Sintaks |
Evaluasi |
Penggunaan Memori |
Terbaik Untuk… |
|
map() |
list(map(func, data)) |
Lazy (hingga dikonsumsi) |
Rendah (iterator) |
Menerapkan fungsi yang sudah ada dan bernama ke sebuah iterable. |
|
List Comprehension |
[func(x) for x in data] |
Eager (seketika) |
Tinggi (membuat lis t baru) |
Transformasi sederhana, pemfilteran, dan membuat list baru. |
|
Ekspresi Generator |
(func(x) for x in data) |
Lazy (hingga dikonsumsi) |
Rendah (iterator) |
Transformasi sederhana, pipeline hemat memori. |
|
itertools.starmap() |
list(starmap(func, data)) |
Lazy (hingga dikonsumsi) |
Rendah (iterator) |
Menerapkan fungsi ke iterable dari iterable (mis., daftar tuple). |
Kapan memilih map() vs. list comprehension
Perbedaan utama antara map() dan list comprehension adalah bahwa yang pertama mengevaluasi secara lazy, sedangkan yang kedua menggunakan evaluasi lazy.
List comprehension sering lebih mudah dibaca untuk ekspresi sederhana dan inline, namun segera membuat list baru, yang dapat menghabiskan ruang memori berharga. Sebaliknya, map() hemat memori, sehingga ideal untuk dataset yang sangat besar ketika membuat list perantara tidak memungkinkan.
Kapan memilih map() vs. ekspresi generator
map() dan ekspresi generator sangat mirip. Keduanya mengevaluasi secara lazy dan karenanya hemat memori.
Ketika ada fungsi yang sudah didefinisikan, map(func, data) sering lebih disukai, karena menjadi sinyal jelas bahwa Anda sedang “memetakan” fungsi tersebut. Namun, ekspresi generator sering lebih mudah dibaca untuk ekspresi baru atau mirip lambda, karena sintaksnya berdiri sendiri.
Kapan memilih map() vs. itertools.starmap()
starmap() adalah versi khusus dari map() yang dirancang khusus untuk iterable berupa tuple (atau iterable lain). Ini menciptakan pembedaan yang jelas: gunakan map() untuk iterable paralel yang independen, dan starmap() saat argumen Anda sudah dikelompokkan bersama.
Fungsi ini secara otomatis membongkar setiap tuple dalam sebagai argumen terpisah untuk fungsi, sehingga alih-alih menulis map(lambda args: func(*args), data), Anda cukup menulis starmap(func, data). Ini membuat kode jauh lebih bersih dan mudah dibaca kapan pun data Anda sudah dikelompokkan dalam tuple.
Perbandingan keterbacaan map()
Keterbacaan adalah faktor utama di Python. Meskipun performa penting untuk dataset besar, kode yang jelas lebih mudah dirawat dan di-debug. Mari lihat bagaimana sintaks dan keterbacaan bervariasi di antara fungsi-fungsi ini menggunakan contoh sederhana menguadratkan nilai dalam list:
numbers = [1, 2, 3, 4]
# --- 1. map() with lambda ---
# Functional, but a bit verbose
squared_map = list(map(lambda x: x * x, numbers))
# --- 2. List Comprehension ---
# Widely considered the most Pythonic and readable for this case
squared_list_comp = [x * x for x in numbers]
# --- 3. Generator Expression ---
# Identical to list comp., but lazy.
# Requires a list() call to print.
squared_gen_exp = list((x * x for x in numbers))
# --- 4. map() with a named function ---
# Very readable if the logic is complex
def square(x):
return x * x
squared_map_func = list(map(square, numbers))
Keempat pendekatan menghasilkan [1, 4, 9, 16].
Jika Anda bersikeras kapan memilih yang mana, berikut rekomendasi saya:
-
Untuk ekspresi sederhana dan membuat list baru, gunakan list comprehension. Ini ringkas, mudah dibaca, dan standar komunitas.
-
Untuk menerapkan fungsi yang sudah ada, gunakan
map(). Dalam banyak kasus, ini terlihat lebih bersih daripada list comprehension, meski beberapa panduan gaya tidak sependapat. -
Untuk dataset besar di mana memori penting, gunakan
map()tanpa langsung memanggillist()atau ekspresi generator. Keduanya lazy. Pilihmap()saat menggunakan ulang fungsi yang sudah ada, dan ekspresi generator saat logikanya inline. -
Untuk logika kompleks (beberapa pernyataan, kondisi, dsb.), definisikan fungsi bernama dengan def dan gunakan
map()(atau for loop biasa). Ini jauh lebih mudah dibaca, di-debug, dan diuji dibanding lambda kompleks atau comprehension multi-baris.
Kesimpulan
Fungsi map() di Python adalah alat yang kuat untuk transformasi data yang efisien. Fitur utamanya adalah lazy evaluation, yang memungkinkan fungsi ini mengembalikan iterator dan memproses item sesuai permintaan. Ini membuatnya sangat hemat memori untuk dataset besar, tidak seperti list comprehension yang membangun list baru di memori.
Ingatlah bahwa karena menghasilkan iterator, Anda harus mengonversi hasilnya ke koleksi konkret, seperti list atau tuple, jika perlu mengakses nilai segera atau menggunakannya beberapa kali.
Ke depan, penggunaan pola fungsional di Python menjadi semakin canggih. Area penting untuk pengembangan adalah integrasi map() dengan sistem type-hinting Python. Menguasai cara menerapkan definisi tipe yang presisi pada transformasi map() yang kompleks akan penting untuk menulis kode yang tangguh dan siap masa depan.
Jika Anda ingin mengembangkan pengetahuan baru ini dan belajar menjadi pro Python sejati, pastikan untuk mendaftar di skill track pemrograman Python.
FAQ Python map()
Bagaimana perbandingan performa fungsi map() dengan list comprehension?
map() lebih hemat memori karena lazy evaluation, sedangkan list comprehension bersifat eager dan membuat seluruh list di memori sekaligus.
Dapatkah Anda memberikan contoh penggunaan map() dengan beberapa iterable?
Sebagai contoh, list(map(lambda x, y: x + y, [1, 2], [10, 20])) menjumlahkan elemen dari dua list, menghasilkan [11, 22].
Apa keuntungan menggunakan map() dibanding for loop?
map() lebih ringkas, sesuai gaya pemrograman fungsional, dan sangat hemat memori karena mengembalikan iterator lazy.
Bagaimana cara kerja lazy evaluation pada fungsi map()?
Fungsi ini mengembalikan iterator yang menghitung nilai baru setiap item hanya saat Anda melakukan iterasi terhadapnya, alih-alih menghitung semua nilai di awal.
Apakah ada jebakan umum yang perlu dihindari saat menggunakan map()?
Ya, jebakan umum meliputi TypeError (akibat fungsi yang tidak callable atau argumen yang bukan iterable) dan penggunaan fungsi dengan efek samping (seperti memutasi objek).
Saya adalah penulis konten data science. Saya senang membuat konten seputar topik AI/ML/DS. Saya juga mengeksplorasi alat AI baru dan menuliskannya.

Fungsi
map()di Python adalah alat built-in yang kuat yang memfasilitasi pola pemrograman fungsional untuk transformasi data. Jika Anda ingin memproses dataset besar, membersihkan data teks, atau melakukan perhitungan massal, maka fungsimap()dapat sangat membantu untuk meningkatkan produktivitas.Dalam tutorial ini, saya akan menunjukkan sintaks, penerapan praktis, dan teknik lanjutan dari fungsi
map()di Python. Kita juga akan membahas lazy evaluation untuk efisiensi memori dan membandingkanmap()dengan alternatif seperti list comprehension, serta membahas praktik terbaik untuk performa optimal.Memahami iterator hanyalah langkah pertama untuk menulis kode yang efisien. Untuk benar-benar menguasai manipulasi data, Anda memerlukan kotak peralatan pemrograman Python yang lengkap, mencakup mulai dari penanganan error hingga iterable tingkat lanjut.
Sintaks Python map()
Sebelum melihat penggunaan fungsi
map(), mari kita pahami cara kerjanya. Memahami sintaks dan perilakunya membantu kita mengaplikasikannya secara lebih efektif.Dasar-dasar fungsi map()
Fungsi
map()adalah utilitas bawaan Python yang menerapkan fungsi tertentu pada setiap item dalam sebuah iterable (seperti list, tuple, atau string) dan mengembalikan sebuah iterator berisi hasil transformasi. Hasilnya, fungsi ini mendorong sifat immutability dan reusable code, yang penting dalam pipeline pemrosesan data dan prapemrosesan fitur untuk model machine learning.Sintaksnya sederhana, seperti di bawah ini:
Parameter
function, yang bisa berupa fungsi bawaan sepertilen()atau fungsi kustom, diterapkan pada setiap item dalamiterable. Kita juga bisa menambahkan beberapa iterable untuk memungkinkan pemetaan paralel. Ini akan dibahas nanti.Berbeda dengan eager evaluation (yang menghitung semuanya di awal),
map()menggunakan lazy evaluation. Fungsi ini mengembalikan objek map, sebuah iterator yang menghasilkan nilai sesuai permintaan. Perhitungan ditunda hingga Anda melakukan iterasi, sehingga menghemat memori untuk dataset besar.Sebagai gambaran cepat, pertimbangkan contoh sederhana untuk menguadratkan angka:
Nilai parameter dan nilai kembalian
Fungsi
map()memerlukan setidaknya dua parameter: fungsi yang dapat dipanggil dan sebuah iterable. Iterable tambahan opsional memungkinkan broadcasting fungsi ke urutan yang dijajar, sehingga cocok untuk operasi tervektorisasi miripapply_along_axis()milik NumPy.Di Python 3,
map()mengembalikan objek map, sebuah turunan iterator, bukan list. Perubahan ini meningkatkan efisiensi memori, karena tidak mengalokasikan ruang untuk seluruh hasil sejak awal. Untuk mematerialkan hasil, konversikan secara eksplisit:Ke list:
list(map(function, iterable))Ke set:
set(map(function, iterable))Iterasi langsung:
for item in map(function, iterable): ..Berikut cuplikan kode yang memperlihatkan konversi:
Untuk ikhtisar cepat berbagai operasi Python yang digunakan sepanjang tutorial ini, saya sarankan melihat lembar contekan Python ini.
Transisi dari Python 2 ke Python 3
Di Python 2,
map()secara eager mengembalikan list, yang bisa membengkakkan memori untuk input besar—jebakan umum pada skrip data lama. Objekmapyang lazy di Python 3 mengubah ini, selaras dengan protokol iterator untuk skalabilitas di lingkungan big data seperti PySpark.Implikasinya? Penanganan dataset masif lebih mulus tanpa error Out of Memory (OOM), meski membutuhkan konversi eksplisit untuk pengindeksan. Misalnya,
my_map[0]tidak akan berfungsi, sehingga kita harus menggunakannext(iter(my_map))sebagai gantinya.Jika Anda terbiasa dengan logika berbasis list, lihat kursus Python untuk pengguna MATLAB untuk memudahkan peralihan dari operasi tervektorisasi ke iterator Python.
Cara Menggunakan map() di Python
Setelah melihat dasar-dasarnya, mari kita implementasikan fungsi
map(). Kita akan melihat cara paling umum menerapkanmap(), mulai dari fungsi bawaan sederhana hingga transformasi multi-iterable yang lebih kompleks.Penggunaan dasar map()
Cara paling langsung menggunakan
map()adalah dengan fungsi bawaan. Misalnya Anda memiliki daftar string dan ingin mengetahui panjang masing-masing. Untuk menerapkan fungsimap():Identifikasi iterable Anda:
words = ['apple', 'banana', 'cherry']Identifikasi fungsi Anda: Fungsi bawaan
len().Terapkan map():
map(len, words)Konversi ke list:
list(map(len, words)Mari lihat kodenya di bawah:
Seperti terlihat, ini lebih ringkas dibanding menulis for loop, menambahkan ke list baru, dan mengelola state dari list tersebut.
Menggunakan map() dengan fungsi lambda
Sering kali, operasi yang ingin Anda lakukan itu sederhana dan sekali pakai. Alih-alih mendefinisikan fungsi penuh dengan
def, Anda dapat menggunakan fungsi lambda, yaitu fungsi kecil, anonim, satu baris.Ini sangat umum dalam pemrosesan data. Misalnya, jika Anda ingin menguadratkan daftar angka, fungsi lambda adalah pilihan yang tepat. Mari lihat contohnya di bawah:
Menggunakan fungsi lambda dengan
map()direkomendasikan dalam kasus berikut:Transformasinya sederhana (idealnya satu ekspresi).
Fungsinya tidak digunakan kembali di bagian lain kode Anda.
Untuk mempelajari lebih lanjut tentang fungsi lambda, lihat tutorial interaktif Python lambda ini.
Menggunakan map() dengan fungsi buatan pengguna
Untuk transformasi yang lebih kompleks atau berulang, gunakan fungsi kustom yang didefinisikan dengan kata kunci
def. Ini membuat kode Anda lebih mudah dibaca, modular, dan mudah diuji.Misalnya Anda memiliki daftar suhu dalam Celsius dan perlu mengonversinya ke Fahrenheit. Kita bisa melakukannya sebagai berikut:
Menggunakan fungsi dengan nama deskriptif, seperti
celsius_to_fahrenheit(), menjelaskan maksud kode dengan jelas, sehingga menjadi praktik terbaik untuk logika bisnis khusus.Menggunakan map() dengan banyak iterable
Salah satu fitur kuat
map()adalah kemampuannya memproses beberapa iterable secara bersamaan. Untuk melakukannya, fungsi Anda harus menerima jumlah argumen yang sama dengan jumlah iterable yang Anda berikan.Misalkan Anda memiliki dua daftar angka dan ingin menjumlahkannya per elemen:
Bagaimana jika ukuran iterable berbeda? Fungsi
map()akan berhenti memproses segera setelah iterable terpendek habis, sehingga output memiliki panjang sama dengan iterable terpendek. Mari lihat contohnya:Perilaku ini dapat diprediksi dan bermanfaat, mencegah pengecualian
IndexError. Jika Anda perlu memproses semua elemen dan mengisi nilai default untuk daftar yang lebih pendek, Anda dapat menggunakanitertools.zip_longest().Selanjutnya, mari lihat beberapa kasus penggunaan sehari-hari untuk fungsi
map().Kasus Penggunaan map() Python yang Umum
Fungsi
map()serbaguna dan sangat berguna untuk banyak tugas pemrosesan dan pembersihan data yang umum. Mari lihat di mana fungsi ini paling bermanfaat.Melakukan perhitungan pada list
Ini adalah kasus penggunaan paling klasik. Ketika Anda memiliki daftar angka dan perlu menerapkan operasi matematis yang seragam ke setiap elemen,
map()adalah solusi yang bersih dan efisien.Kita sudah melihat contoh bagusnya dengan konversi dari Celsius ke Fahrenheit di bagian sebelumnya. Skenario umum lainnya adalah menerapkan rumus finansial, seperti menghitung pajak penjualan atau mengonversi mata uang.
Bayangkan Anda memiliki daftar harga produk dalam USD dan perlu mengonversinya ke EUR. Kita bisa melakukannya seperti berikut:
Pola ini jauh lebih mudah dibaca daripada
forloop, terutama saat logika konversi kompleks dan sebaiknya disimpan dalam fungsinya sendiri.Memproses string secara massal
Pembersihan data sering kali melibatkan pemrosesan volume besar data teks. Anda mungkin memiliki ribuan entri teks yang perlu dinormalisasi sebelum analisis. Fungsi
map()sangat cocok untuk menerapkan metode string ke seluruh list.Sebagai contoh, mari bersihkan daftar nama dengan menghapus spasi yang tidak diinginkan dan menstandarkan kapitalisasi:
Kemampuan untuk merangkai operasi
map()(karena masing-masing mengembalikan iterator) penting untuk menangani pipeline data yang efisien.Memfilter dan memetakan data
Sering kali, Anda tidak ingin mentransformasi setiap item. Anda hanya ingin mentransformasi item yang memenuhi kondisi tertentu. Ini adalah pola umum dalam analisis data, dan mudah diatasi dengan menggabungkan
map()denganfilter()milik Python.Fungsi
filter(function, iterable)bekerja mirip denganmap(), tetapi hanya mengembalikan item untuk yang fungsinya menghasilkanTrue.Misalkan kita memiliki daftar pembacaan sensor, dan kita ingin menguadratkan hanya nilai positif, mengabaikan nilai negatif (yang mungkin error). Kita bisa melakukan:
Filter: Pertama, gunakan
filter()untuk mendapatkan hanya angka positif.Map: Kemudian, gunakan
map()untuk menerapkan fungsi kuadrat ke hasil yang telah difilter.Karena
map()danfilter()keduanya lazy, proses dua langkah ini sangat hemat memori. Tidak ada list perantara yang dibuat. Polafilterlalumapini merupakan alternatif kuat untuk list comprehension Python yang lebih kompleks.Contoh Praktis map() dalam Aksi
Setelah melihat konsep dasar dan kasus penggunaan umum, mari tinjau beberapa contoh praktis spesifik yang menunjukkan bagaimana fungsi
map()menyediakan sintaks yang bersih dan efisien untuk berbagai tugas transformasi data.Mengonversi ke huruf kapital
Ini tugas klasik pemrosesan string. Diberi daftar string, Anda dapat menggunakan fungsi
map()dengan metode bawaanstr.upper()untuk mengonversi setiap item menjadi huruf kapital, seperti berikut:Mengekstrak karakter pertama dari string
Terkadang Anda perlu mengekstrak bagian informasi tertentu dari setiap item. Di sini, kita bisa menggunakan fungsi
lambdauntuk mengambil karakter pertama (pada indeks0) dari setiap string dalam list.Menghapus spasi dari string
Seperti kita lihat pada bagian pemrosesan string, pembersihan spasi adalah langkah mendasar dalam penyiapan data teks.
map()denganstr.strip()adalah cara paling Pythonic untuk melakukan ini.Untuk lebih banyak cara mengelola data string dan list, tutorial interaktif tentang fungsi dan metode list di Python menyediakan banyak contoh.
Memutakhirkan data dalam framework (mis., Django)
Dalam aplikasi web atau berbasis data, Anda sering menerima data sebagai daftar dictionary (seperti payload JSON). Fungsi
map()dapat digunakan untuk menyiapkan data untuk pembaruan basis data, seperti di Django atau saat bekerja dengan MongoDB.Bayangkan kita memiliki daftar dictionary yang merepresentasikan pembaruan produk, dan kita perlu menambahkan stempel waktu
processedpada masing-masing sebelum dikirim ke basis data:Pola ini ideal untuk pembaruan batch dan benar-benar menunjukkan nilai dari memahami dictionary.
Menghasilkan elemen HTML
Bagi pengembang web,
map()bisa menjadi mesin templat sederhana. Anda dapat mengubah daftar item data menjadi daftar string HTML yang siap dirender. Berikut contoh cara mengubah list Python menjadi daftar HTML tak berurutan:Aplikasi Lanjutan map() di Python
Meskipun
map()sangat baik untuk transformasi satu-ke-satu yang sederhana, kekuatannya yang sesungguhnya terlihat pada skenario yang lebih kompleks. Mari lihat beberapa pola lanjutan di manamap()menjadi komponen kunci strategi pemrosesan data yang canggih.Pemrosesan multi-iterable
Kita telah menyinggung penggunaan
map()dengan beberapa iterable, dan ini merupakan pola yang mendasar bagi banyak komputasi data dan sains tingkat lanjut. Saat Anda memberikan beberapa iterable,map()bertindak seperti resleting, memberi makan elemen ke-i dari setiap iterable ke fungsi Anda, artinya jumlah argumen harus sesuai dengan jumlah iterable.Sebagai contoh, untuk menghitung total nilai berbagai produk dalam inventaris, Anda mungkin memiliki tiga daftar terpisah. Mari lihat bagaimana
map()digunakan di sini:Seperti disebutkan sebelumnya,
map()berhenti pada iterable terpendek. Ini adalah fitur yang disengaja untuk mencegah pengecualianIndexError. Jika logika Anda mengharuskan memproses semua item dari daftar terpanjang (misalnya mengisi nilai default), ingat untuk menggunakanitertools.zip_longest(). Anda dapat mempelajarinya bersama banyak fungsi berguna lainnya dalam kursus tentang menulis kode Python yang efisien.itertools.starmap() untuk iterable bertingkat
Apa yang terjadi ketika data Anda sudah “dijajar” menjadi daftar tuple? Ini sangat umum saat bekerja dengan hasil kueri basis data, file CSV, atau pasangan koordinat.
Misalkan Anda memiliki daftar titik
(x,y)seperti di bawah, dan Anda ingin menghitung hasil kali tiap pasangan.Anda bisa menggunakan
lambdadenganmap(), tetapi agak canggung dengan fungsi bertingkat panjang di dalamnya:Solusi yang jauh lebih bersih dan Pythonic adalah
itertools.starmap(). Fungsi ini menerima sebuah fungsi dan satu iterable dari iterable (seperti daftar tuple kita). Ia kemudian membongkar setiap tuple dalam sebagai argumen bagi fungsi tersebut. Mari lihat praktiknya:starmap()adalah alat yang tepat ketika argumen fungsi Anda sudah dikemas sebelumnya dalam tuple. Pola ini sangat berguna saat memproses data geospasial, seperti daftar koordinat(latitude, longitude). Untuk pendalaman konsep ini, saya merekomendasikan kursus tentang bekerja dengan data geospasial di Python.Integrasi pemrograman fungsional
Fungsi
map()sangat berguna dalam pemrograman fungsional. Kita dapat menggabungkannya dengan alat fungsional lain sepertifilter()danfunctools.reduce()untuk membangun pipeline pemrosesan data yang bersih dan sangat efisien.Kita sudah melihat kombinasi
filter()danmap(). Sekarang, mari lihat cara menggunakanreduce(), yang mengagregasi (atau “mereduksi”) sebuah iterable menjadi satu nilai kumulatif.Misalkan Anda ingin mencari jumlah kuadrat dari semua angka ganjil dalam daftar tertentu. Kita bisa melakukan seperti berikut:
Ini adalah pola yang kuat. Karena
map()danfilter()sama-sama mengembalikan iterator lazy, seluruh operasi ini sangat hemat memori. Tidak ada list perantara besar yang dibuat di memori. Data mengalir melalui pipeline, item demi item.Lazy Evaluation dan Manajemen Memori
Salah satu fitur paling penting dari
map()di Python 3 adalah penggunaan lazy evaluation. Memahami konsep ini diperlukan untuk menulis kode yang efisien dan skalabel, terutama bagi praktisi data yang menangani dataset besar secara rutin. Di bagian ini, kita akan melihat cara kerjanya.Manfaat lazy evaluation
Di Python 3,
map()tidak langsung menjalankan fungsi Anda dan mengembalikan list. Sebaliknya, ia mengembalikan objekmap, yaitu sebuah iterator. Iterator ini “tahu” fungsi dan data apa yang digunakan, tetapi tidak benar-benar melakukan perhitungan sampai Anda secara eksplisit meminta item berikutnya.Perhitungan “tepat waktu” ini memiliki manfaat besar, seperti:
Efisiensi Memori: Objek
maphanya menempati sejumlah kecil memori konstan, terlepas apakah memproses 10 item atau 10 miliar. Ia tidak membuat list baru di memori untuk menampung seluruh hasil.Performa pada Dataset Besar: Saat Anda melakukan iterasi pada objek
map(misalnya dalamforloop), ia menghitung dan menghasilkan satu nilai pada satu waktu. Ini memungkinkan Anda memproses berkas besar atau aliran data yang terlalu besar untuk dimuat sekaligus ke memori.Dapat Dirangkaikan: Seperti yang kita lihat pada bagian pemrograman fungsional, iterator lazy dapat dirangkaikan (mis.,
map()setelahfilter()). Karena tidak ada list perantara yang dibuat, data mengalir melalui pipeline satu per satu item, yang sangat efisien.Bandingkan ini dengan list comprehension, yang menggunakan evaluasi eager. Pertimbangkan contoh ini:
Kode ini akan langsung mencoba membuat list dengan 10 juta angka, yang berpotensi mengonsumsi banyak RAM.
Menggunakan ekspresi generator
Ekspresi generator adalah padanan lazy dari list comprehension. Bentuknya sangat mirip, tetapi berperilaku seperti
map()dalam hal memori.Kode di atas juga membuat iterator yang hemat memori, seperti halnya
map(). Pilihan antaramap()dan ekspresi generator sering bergantung pada keterbacaan.map()bisa lebih jelas saat menerapkan fungsi yang kompleks dan sudah ada, sementara ekspresi generator sering lebih mudah dibaca untuk ekspresi sederhana dan inline.Mari bandingkan penggunaan memori untuk operasi-operasi ini:
Catatan: 'Peak RAM' untuk Objek Map/Generator di sini mengacu pada memori yang dialokasikan untuk objek iterator itu sendiri, bukan memori list penuh yang akan dihasilkan jika dikonversi, menunjukkan sifat lazy-nya.
Mengonversi objek map ke iterable
Karena
map()mengembalikan iterator lazy, sering kali Anda perlu mematerialkannya atau mengonversinya menjadi koleksi konkret untuk benar-benar menggunakan hasilnya.Anda sebaiknya mengonversi objek
mapketika Anda perlu:Melihat semua hasil sekaligus (mis., untuk
print()).Mengakses elemen berdasarkan indeks (mis.,
results[0]).Mendapatkan panjang hasil (mis.,
len(results)).Memberikan hasil ke fungsi yang memerlukan list atau set.
Melakukan iterasi atas hasil beberapa kali. (Objek
map, seperti semua iterator, dapat habis.) Anda hanya bisa melakukan loop sekali.Berikut cara mengonversi objek
map:Untuk mengonversi ke dictionary (jika output berupa pasangan key-value), Anda bisa menggunakan
map()dengandict(), namun sering kali dictionary comprehension Python lebih jelas.Inti utamanya adalah bersikaplah sengaja. Biarkan
map()tetap menjadi iterator lazy selama mungkin dalam pipeline Anda, dan hanya konversi ke list pada saat terakhir ketika Anda benar-benar memerlukan hasil konkret.