بايثون والمرونة في البرمجة – الدليل الشامل لفهم comprehensions في البايثون

0 3٬523

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

نتحدث في هذا المقال عن الخاصية الرائعة في بايثون وهي python comprehensions والتي تمنح المبرمج القدرة على تعريف تراكيب بايثون مثل list بسطر واحد فقط. في نهاية هذا المقال سيكون لديك المعرفة الكاملة حول كيفية استخدام comprehensions في بايثون.

ما هي comprehensions في بايثون ؟

ببساطة هي صيغة سهلة تُتيح لنا إنشاء تراكيب مُعينة في بايثون. تم تقديم هذه الخاصية في بايثون 2 وكانت مُقتصرة على list comprehension، ثم جاءت بايثون 3 لتضيف امكانية انشاء تراكيب set و dictionary من خلال هذه الخاصية.

تُقدم بايثون لنا امكانية انشاء أربعة أنواع من comprehensions هي:

  • القوائم lists comprehensions
  • القاموس dictionary comprehensions
  • المجموعة set comprehensions
  • الموُلد generator comprehensions

lists comprehensions في بايثون

من خلال list comprehension نستطيع انشاء قائمة بطريقة سهلة ويسيرة. في البداية، سنتعرف على الطُرق التي من خلالها يُمكن تعريف قائمة.

لنفترض أنه لدينا قائمة بأسعار منتجات مُعينة، ونُريد انشاء قائمة أخرى تتضمن أسعار الضريبة على هذه المنتجات. الطُرق التي من الممكن الحصول على قائمة أسعار الضريبة على المنتجات هي كالتالي:

استخدام for loop

items_prices = [100,124,807,90,60,30,22,37,40,57]
tax_rate = 0.145

taxes = []
for item in items_prices:
taxes.append(item * tax_rate)
print(taxes)

في البداية نُعرف قائمة أسعار المنتجات في قائمة باسم items_prices ثم نُعرف بعدها متغير يُمثل نسبة الضريبة التي سيتم فرضها على المنتجات.

الطريقة الأولى التي سنستخدمها في إنشاء قائمة الضريبة هي من خلال استخدام جُملة for loop. نُعرف قائمة فارغة باسم taxes وستكون هذه القائمة هي قائمة اسعار الضريبة على المنتجات. نُعرف بعدها جملة for والتي بواسطتها نمر على جميع المنتجات في قائمة items_prices ثم نضرب سعر كل منتج في نسبة الضريبة، ثم نحفظ النتيجة في قائمة taxes.

تستطيع تجربة الطريقة الأولى مباشرةً عبر الأداة التفاعلية التالية:

[datacamp_exercise lang="python"] 
[datacamp_sample_code] 
items_prices = [100,124,807,90,60,30,22,37,40,57] 
tax_rate = 0.145 
taxes = [] 
for item in items_prices: 
    taxes.append(item * tax_rate) 
print(taxes) 
[/datacamp_sample_code] 
[/datacamp_exercise]

استخدام دالة map

الطريقة الثانية في إنشاء قائمة الضريبة على الأسعار هو استخدام دالة map. نستخدم هذه الدالة في تطبيق دالة او عملية ما على جميع عناصر كائن iterable مثل القوائم والقاموس. في مثالنا، سنُعرف دالة باسم get_item_tax والتي تأخذ قيمة ما وتُرجع القيمة مضروبة في نسبة الضريبة.

items_prices = [100,124,807,90,60,30,22,37,40,57]
tax_rate = 0.145

def get_item_tax(item):
return item * tax_rate

taxes = map(get_item_tax,items_prices)

print(list(taxes))

لبناء قائمة أسعار الضريبة نُمرر لدالة map كل من دالة get_item_tax وقائمة أسعار المنتجات، وستقوم دالة map بالمرور على جميع عناصر قائمة الأسعار بطريقة عنصر-عنصر وتضرب قيمة كل عنصر بنسبة الضريبة المُحددة، ثم تُرجع النتيجة على شكل lazy iterable. للحصول على القائمة النهائية نمرر نتيجة دالة map للباني الخاص بالقوائم list للحصول على القائمة.

[datacamp_exercise lang="python"]
[datacamp_sample_code]
items_prices = [100,124,807,90,60,30,22,37,40,57]
tax_rate = 0.145

def get_item_tax(item):
    return item * tax_rate
taxes = map(get_item_tax,items_prices)
print(list(taxes))
[/datacamp_sample_code]
[/datacamp_exercise]

استخدام list comprehension

نلاحظ أن أول طريقتين تحتاج لأكثر من سطر برمجي لإتمام الهدف المنشود. من خلال list comprehension في بايثون نستطيع تحقيق الهدف باستخدام سطر واحد كما يلي:

items_prices = [100,124,807,90,60,30,22,37,40,57]
tax_rate = 0.145

#create the list by using list-comprehension
taxes = [item*tax_rate for item in items_prices]

print(taxes)

يتكون التعبير الخاص بـ list comprehension من عدة أجزاء هي:

  1. Input Sequence: وهو كائن iterable وهو القائمة المُدخلة، حيث في مثالنا هي قائمة أسعار المنتجات.
  2. Variable: مُتغير يُمثل العنصر في القائمة المُدخلة، وهو item في المثال السابق.
  3. Optional if expression: هو شرط اختياري يُمكن استخدامه لإضافة شرط يجب تحقيقه في المتغير.
  4. Output expression: تعبير يُولد عناصر القائمة الجديدة من عناصر القائمة المُدخلة التي تحقق الشرط الاختياري عند استخدامه

فيما يخص output expression في المثال السابق، عرفنا التعبير من خلال ضرب قيمة العنصر بنسبة الضريبة item * tax_rate.

استخدام الجُملة الشرطية مع list comprehension

يُمكننا استخدام جملة شرطية عند إنشاء القوائم. لنفترض أننا نُريد احتساب الضريبة على الأسعار التي تكون قيمتها أكبر من 50.

سنضيف عندها الجملة الشرطية داخل التعبير المستخدم كما يلي:

items_prices = [100,124,807,90,60,30,22,37,40,57]
tax_rate = 0.145

#create the list by using list-comprehension
taxes = [item*tax_rate for item in items_prices if item >= 50]
print(taxes)

تدريب 1

أجري التعديلات اللازمة على الشيفرة البرمجية التالية، بحيث نحصل على قائمة تتضمن الأرقام الموجودة في القائمة المُدخلة مرفوعة للأُس الثاني:

[datacamp_exercise lang="python"]
    [datacamp_pre_exercise_code]
    [/datacamp_pre_exercise_code]
    [datacamp_sample_code]
        a_list = [1, '4', 9, 'a', 0, 4]

        squared_ints = [ ......... ]

        print(squared_ints)
        # [ 1, 81, 0, 16 ]
    [/datacamp_sample_code]
    [datacamp_solution]
        a_list = [1, '4', 9, 'a', 0, 4]

        squared_ints = [ e**2 for e in a_list if type(e) == int ]

        print(squared_ints)
        # [ 1, 81, 0, 16 ]
    [/datacamp_solution]
    [datacamp_sct]
        test_object('squared_ints')
        success_msg("Great job! Pythonat welcomes you.")
    [/datacamp_sct]
    [datacamp_hint]
     use type() function to test if the item is Int or not.
    [/datacamp_hint]
[/datacamp_exercise]

ما هي الفائدة من استخدام list comprehension في بايثون؟

  • تُعتبر هذه الخاصية طريقة بايثونية  Pythonic Way مُفضلة لإنشاء القوائم كلما أمكن استخدامها.
  • أكثر سهولة في القراءة والفهم.
  • تسمح لمُفسر بايثون من تحسين طريقة إنشاء القوائم Optimized Creation.
  • تُقدم طريقة آلية لبناء القوائم دون الحاجة لتعريف حلقات تكرار او استخدام دالة map.

أمثلة أساسية لإنشاء القوائم باستخدام list comprehension

1- إنشاء قائمة بالأرقام الزوجية بين 0 و 100:

evens_0_to_100 = [x for x in range(1,101) if x%2 == 0]

2- انشاء قائمة بأرقام مضروبة في رقم 3:

multiply_by_3 = [x * 3 for x in range(100)]

3- الحصول على أحرف كلمة Pythonat:

letters = [ letter for letter in 'Pythonat']

4- إنشاء قائمة تتضمن قوائم داخلية وفق شروط معينة:

x = [1,2,3,4,5,6]
y = [6,5,4,3,2,1]

#build list if item in x != item in y and item in x greater than 3
l = [[a,b] for a in x for b in y if (a != b and a>=3)]

لاحظ في المثال الأخير أننا استخدمنا أكثر من جملة for داخل list comprehension.

تدريب 2

أنشئ قائمة بالأسماء التي يتعدى عدد أحرفها 5 أحرف:

 

[datacamp_exercise lang="python"]
    [datacamp_pre_exercise_code]
    [/datacamp_pre_exercise_code]
    [datacamp_sample_code]
      names = ['Ibrahim', 'Sara', 'Duaa', 'Mahmoud','Baraa','Malak']
      
      #use list comprehension to get new names
      names_gr_5 = [ ...................... ]
    [/datacamp_sample_code]
    [datacamp_solution]
      names = ['Ibrahim', 'Sara', 'Duaa', 'Mahmoud','Baraa','Malak']
      
      #use list comprehension to get new names
      names_gr_5 = [name for name in names if len(name) >= 5]
    [/datacamp_solution]
    [datacamp_sct]
        test_object('names_gr_5')
        success_msg("Great job! Pythonat welcomes you.")
    [/datacamp_sct]
    [datacamp_hint]
     use len() function to get the length of a text variable
    [/datacamp_hint]
[/datacamp_exercise]

المجموعة set comprehensions في بايثون

النوع الثاني من comprehension في بايثون هو set comprehension والذي من خلاله يُمكن إنشاء المجموعات بطريقة سهلة ويسيرة ومفهومة في نفس الوقت.

لنفترض أنه لدينا قائمة تحتوي على أسماء مُعينة ونريد أن نُنشئ مجموعة بالأسماء التي طولها أقل من 4 أحرف من هذه القائمة، نكتب التالي لذلك:

names = ['Ibrahim', 'Sara', 'Duaa', 'Mahmoud','Baraa','Malak']

names_set = {name for name in names if len(name) <= 4}

لاحظ أننا استخدمنا الأقواس المُزهرة { } لإنشاء المجموعة، وهذا يختلف عن الأقواس المُربعة التي استخدمناها في انشاء القوائم عبر خاصية comprehension.

جرب تشغيل الشيفرة البرمجية السابقة في الأسفل:

[datacamp_exercise lang="python"]
   [/datacamp_exercise]

القاموس dictionary comprehensions في بايثون

بنفس الطريقة مع القواميس، نستطيع استخدام خاصية comprehension في بناء القواميس. في المثال التالي، نجمع قيم المفاتيح في القاموس المُدخل، ونوحد المفاتيح التي لها أكثر من حالة lower & upper case:

mcase = {'a':10, 'b': 34, 'A': 7, 'Z':3}

mcase_frequency = { k.lower() : mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase.keys() }

لاحظ أننا هنا استخدمنا أيضًا الأقواس المُزهرة كما في المجموعات.

الموُلد generator comprehensions في بايثون

هذا النوع هو نفسه list comprehension. الفرق الوحيد هو في الأداء، حيث لا يتطلب حجز ذاكرة للقائمة كاملةً. النتيجة هو مُولد generator، ويُمكن الحصول على العناصر في المُولد الجديد عند استدعاءه في حلقة تكرار او استخدام دالة next كما يلي:

multiples_gen = (i for i in range(30) if i % 3 == 0)
print(multiples_gen)
#<generator object <genexpr> at 0x000001B709C87750>

#using next function to get items
print( next(multiples_gen) )
print( next(multiples_gen) )

#using for loop to get items
for x in multiples_gen:
print(x)

في بايثون تذكر دائمًا

  • خاصية comprehension في بايثون هي طريقة سهلة ومُفضلة لتعريف تراكيب القوائم والمجموعات والقواميس.
  • تعتير هذه الخاصية أسرع وأكثر كفاءة.
  • لا ينبغي علينا استخدام comprehension لكتابة شيفرة طويلة ومُعقدة، فالهدف هنا هو التسهيل وليس التعقيد.
  • كل list comprehension يُمكن إعادة كتابتها باستخدام for loop ولكن ليس كل for loop يُمكن إعادة كتابتها كـ list comprehension.

بذلك نكون قد شرحنا موضوع comprehension في لغة البرمجة البايثون، وكيف يُمكن التعامل معها وكيف يُمكن إنشاء القوائم والقواميس والمجموعات والمولدات باستخدام هذه الخاصية. نتمنى أن نكون وُفقنا في إيصال المعلومة بالشكل الصحيح، ونسعد بأي ملاحظة في التعليقات. كما نتمنى منكم مشاركة مقالات بايثونات في منصات التواصل الاجتماعي مثل تويتر وفيسبوك حتى تعم الفائدة.

اترك ردًا

Your email address will not be published.