استغني عن حلقات For في بايثون بتوابع Map و Filter و Reduce

سنتعلم في هذه المقالة كيف نقوم بكتابة كود برمجي في بايثون أكثر احترافية وسرعة في التنفيذ باستخدام توابع تشكل نقاط قوة لبايثون وتميّزها عن غيرها من لغات البرمجة.

Map and Filter Function in Python - DZone AI
map, filter, reduce في لغة البرمجة بايثون

الحلقات البرمجية في بايثون

هل سبق لك أن نظرت إلى الكود الخاص بك وشاهدت شلالًا من حلقات for؟ هل تجد نفسك مضطرًا لتحديق عينيك والانحناء نحو شاشتك لكي تراجع كودك البرمجي وتعرف ماهي الاقسام التي تنتمي للحلقة وماهي الاقسام التي لا تنتمي؟

حلقات For هي جوكر فعال لحل المشكلات ، ولكن عندما يتعلق الأمر بمسح الشفرة يدويا للحصول على قراءة سريعة لما أنجزته ، أو البحث عن خطأ برمجي ما, سترى كم أن ذلك معقدا في بايثون.


ماهي توابع Map, Filter, Reduce في بايثون؟

يمكن وصف هذه التوابع او العمليات بمايلي:

  • Map في بايثون : تقوم هذه العملية بتطبيق مجموعة من الخطوات على كل عنصر في بنى معطيات ما وتخزين النتائج.
  • Filter في بايثون: تقوم هذه العملية بفلترة بيانات من بنى معطيات ما اعتمادا على شرط ما.
  • Reduce في بايثون: تقوم هذه العملية بإرجاع قيمة تم تمريرها من عنصر إلى أخر.

ما أهمية استخدام Map, Filter, Reduce في بايثون؟

في بايثون هذه التقنيات الثلاثة توجد على شكل تابع, اي أنك تقوم باستدعائها كما تستدعي اي تابع اخر, على سبيل المثال

map(function, my_list)

أيضا كما لاحظت فأنها تحتاج إلى تابع يجب تمريره إليها كبارامتر, بشكل عام يتم كتابة هذا التابع ضمن هذه العمليات كتابع بدون اسم او يمكن استخدام Lambda في بايثون للقيام بهذه المهمة.

يمكن كتابة تابع Lambda بكل بساطة كمايلي:

square = lambda number: number * number

اي انه يقوم بتوليد مربع العدد number*number من أجل عدد مدخل number.

الفرق الجوهري بين Lambda والتوابع العادية في بايثون ان Lambda تأخذ سلسلة واحدة من التعلميات او تعبير expression بينما عندما تقوم بكتابة تابع في بايثون فتستطيع وضع ما أردت من التعابير على عشرات الأسطر.

بالتالي إذا أردت تطبيق تابع يتألف من عدة تعليمات في map يمكنك القيام بمايلي:

def inefficientSquare(number):
   result = number * number
   return resultmap(inefficientSquare, my_list)

الاستغناء عن الحلقات For في بايثون

فيما يلي ثلاثة أمثلة تحوي حلقات For سنقوم باستبدالها ب map, filter, reduce. هذه التوابع تقوم بحساب مربع مجموع الأعداد الفردية في حلقة list.

numbers = [1,2,3,4,5,6]
odd_numbers = []
squared_odd_numbers = []
total = 0# filter for odd numbers
for number in numbers:
if number % 2 == 1:
odd_numbers.append(number)# square all odd numbers
for number in odd_numbers:
squared_odd_numbers.append(number * number)# calculate total
for number in squared_odd_numbers:
total += number# calculate average

لتحويل هذه التابع الأول:

from functools import reduce
numbers = [1,2,3,4,5,6]
odd_numbers = filter(lambda n: n % 2 == 1, numbers)
squared_odd_numbers = map(lambda n: n * n, odd_numbers)
total = reduce(lambda acc, n: acc + n, squared_odd_numbers)

قمنا باستخدام filter لحذف الأعداد الغير فردية او التي لا تحقق الشرط المذكور, ثم قمنا باستخدام map للحصول على مربع كل عدد, وأخيرا جمعنا قيم المربعات باستخدم rdeuce.

قمنا في هذه المقالة بتقديم مثال توضيحي على استخدام map, reduce, filter في بايثون للاستغناء عن الحلقات وجعل الكود البرمجي أوضح وأسرع, اتركوا لنا تعليق في حال وجود أي سؤال.