سطح مقدماتی (Beginner Level)
در پایتون، علاوه بر حلقههای for و while، روشهای دیگری برای پیمایش و تغییر دادهها وجود دارد که از دنیای "برنامهنویسی تابعی" (Functional Programming) وام گرفته شدهاند. سه تابع اصلی در این زمینه map، filter و reduce هستند. این توابع به شما اجازه میدهند بدون نوشتن حلقههای طولانی، عملیات خاصی را روی تمام اعضای یک لیست یا مجموعه انجام دهید.
۱. تابع Map
تابع map یک تابع خاص را روی تکتک اعضای یک لیست (یا هر قابل پیمایش دیگر) اجرا میکند و نتیجه را برمیگرداند.
ساختار کلی:
# Static code (Syntax definition)
map(function, iterable)
در مثال زیر، ما میخواهیم توان دوم اعداد یک لیست را محاسبه کنیم. به جای ساختن یک لیست خالی و استفاده از حلقه for، از map استفاده میکنیم:
معمولاً map را همراه با lambda (توابع بینام) استفاده میکنند تا کد کوتاهتر شود:
۲. تابع Filter
همانطور که از نامش پیداست، filter برای غربال کردن دادهها استفاده میشود. این تابع، یک شرط را روی تکتک اعضا بررسی میکند؛ اگر شرط True باشد، آن عضو نگه داشته میشود و اگر False باشد، حذف میشود.
۳. تابع Reduce
تابع reduce کمی متفاوت است. این تابع تمام اعضای لیست را با هم ترکیب میکند تا در نهایت به یک مقدار واحد برسد (مثلاً جمع کل اعداد یا ضرب کل اعداد).
نکته مهم این است که در پایتون ۳، تابع reduce به ماژول functools منتقل شده و باید import شود.
سطح پیشرفته (Professional Level)
در سطح حرفهای، باید بدانیم چه زمانی از این توابع استفاده کنیم و چه زمانی از جایگزینهای مدرنتر پایتون مثل List Comprehension بهره ببریم. همچنین نکات مربوط به مدیریت حافظه (Memory Efficiency) در دادههای حجیم بسیار حیاتی است.
مقایسه Map/Filter با List Comprehension
اغلب توسعهدهندگان پایتون ترجیح میدهند از List Comprehension استفاده کنند چون خوانایی بالاتری دارد. اما map و filter در شرایط خاص (مثلاً وقتی تابع از قبل تعریف شده است) میتوانند سریعتر باشند.
# Static code (Comparison snippet)
# Using Map
list(map(str, range(10)))
# Using List Comprehension (More Pythonic usually)
[str(x) for x in range(10)]
نکته فنی: Lazy Evaluation (اجرای تنبل)
توابع map و filter در پایتون ۳ یک Iterator برمیگردانند، نه یک لیست کامل. این یعنی دادهها تا زمانی که شما آنها را درخواست نکنید (مثلاً با حلقه یا تبدیل به list()) پردازش نمیشوند. این ویژگی برای کار با دادههای حجیم (Big Data) عالی است چون حافظه رم را اشغال نمیکند.
استفاده از Map با چند ورودی (Multiple Iterables)
یکی از قدرتهای کمتر شناخته شده map این است که میتواند چندین لیست را همزمان دریافت کند. در این حالت، تابع ورودی باید به تعداد لیستها آرگومان داشته باشد.
آرگومان Initializer در Reduce
تابع reduce یک آرگومان سوم اختیاری به نام initializer دارد. این مقدار به عنوان مقدار اولیه در نظر گرفته میشود و اگر لیست خالی باشد، این مقدار به عنوان پیشفرض برگردانده میشود تا از خطا جلوگیری شود.