شرح List Comprehension في Python للمبتدئين بأسلوب عملي واضح
ما المقصود بـ List Comprehension في Python؟
تُعد List Comprehension واحدة من أكثر الأدوات أناقة واختصاراً في لغة Python لإنشاء القوائم. فكرتها الأساسية هي بناء قائمة جديدة انطلاقاً من كائن قابل للتكرار مثل list أو tuple أو set أو string، وذلك بصياغة مختصرة وسهلة القراءة.
بدلاً من كتابة حلقة for كاملة ثم استخدام الدالة append() لإضافة العناصر واحداً تلو الآخر، يمكنك تنفيذ المهمة نفسها في سطر واحد غالباً. وهذا يجعل الشيفرة أكثر وضوحاً في الحالات البسيطة، كما يمنحك مرونة في التصفية والتعديل وإعادة التنسيق.

لماذا تُستخدم List Comprehension؟
تُستخدم هذه الصيغة عندما تريد إنشاء قائمة جديدة بسرعة من بيانات موجودة مسبقاً. وهي مفيدة في مهام كثيرة، مثل:
- نسخ عناصر من قائمة إلى أخرى.
- تعديل كل عنصر قبل تخزينه.
- تصفية العناصر وفق شرط محدد.
- دمج أكثر من حلقة
forفي صياغة مختصرة. - تحسين قابلية القراءة في العمليات البسيطة والمتوسطة.
الصيغة العامة لـ List Comprehension
تُكتب List Comprehension بين أقواس مربعة، وتتكون غالباً من ثلاثة أجزاء رئيسية:
- القيمة أو التعبير الناتج.
- حلقة
for. - شرط اختياري باستخدام
if.

الصيغة الشائعة تكون على هذا النحو:
[expression for item in iterable if condition]
ومن المهم فهم أن الجزء الأول ليس مجرد عنصر ثابت، بل يمكن أن يكون عملية حسابية أو تحويل نصي أو حتى تعبيراً شرطياً.
مثال بسيط على List Comprehension في Python
لنبدأ بأبسط حالة: نسخ عناصر قائمة إلى قائمة جديدة.
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# simple list comprehension
a = [x for x in lst]
print(a)
# output [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
ما يحدث هنا بسيط للغاية: يجري المرور على كل عنصر في lst، ثم يُحفظ في القائمة الجديدة a.
وهذا يكافئ كتابة حلقة for بالشكل التقليدي:
a = []
for x in lst:
a.append(x)
الميزة هنا أنك لست بحاجة إلى إنشاء القائمة الفارغة يدوياً أو استدعاء append() في كل دورة.
تعديل العناصر أثناء الإنشاء
قوة List Comprehension لا تتوقف عند نسخ البيانات، بل يمكنك تعديل القيم مباشرة داخل التعبير:
# add any number to every element of lst and store it in a
a = [x + 1 for x in lst]
# subtract any number from every element of lst and store it in a
a = [x - 1 for x in lst]
# multiply every element of lst and store it in a
a = [x * 2 for x in lst]
هذا الأسلوب ممتاز عندما تحتاج إلى تحويل البيانات بسرعة، مثل زيادة القيم، أو مضاعفتها، أو إعادة تنسيقها قبل عرضها أو تخزينها.
استخدام if داخل List Comprehension
من أكثر الاستخدامات شيوعاً لـ List Comprehension هو تصفية العناصر. يمكنك إضافة شرط if في نهاية التعبير للاحتفاظ بالعناصر التي تحقق شرطاً معيناً فقط.
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# with if condition
c = [x for x in lst if x > 4]
print(c)
# output [5, 6, 7, 8, 9, 10]
هنا، يتم تخزين العناصر الأكبر من 4 فقط في القائمة c.
والصيغة التقليدية المكافئة هي:
c = []
for x in lst:
if x > 4:
c.append(x)
استخدام أكثر من شرط if
يمكنك أيضاً كتابة أكثر من شرط لتضييق نطاق النتائج. في المثال التالي، نحتفظ بالعناصر التي تزيد على 4 وتقبل القسمة على 2:
# with multiple if
d = [x for x in lst if x > 4 if x % 2 == 0]
print(d)
# output [6, 8, 10]
وهذه الشيفرة تعادل:
d = []
for x in lst:
if x > 4:
if x % 2 == 0:
d.append(x)
هذا النمط مناسب عندما تكون شروط التصفية واضحة وقصيرة. أما إذا أصبحت الشروط كثيرة أو متداخلة أكثر من اللازم، فغالباً تصبح الحلقة التقليدية أوضح وأسهل للصيانة.
استخدام if وelse داخل List Comprehension
يمكنك إدخال منطق شرطي كامل داخل التعبير نفسه، بحيث تُعيد قيمة إذا تحقق الشرط، وقيمة أخرى إذا لم يتحقق.
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# with if and else condition
e = [x if x > 4 else 'less than 4' for x in lst]
print(e)
# output ['less than 4', 'less than 4', 'less than 4', 'less than 4', 5, 6, 7, 8, 9, 10]
في هذا المثال، إذا كانت قيمة x أكبر من 4 تُحفظ كما هي، وإلا يُحفظ النص 'less than 4' بدلاً منها.
والشكل التقليدي المقابل هو:
e = []
for x in lst:
if x > 4:
e.append(x)
else:
e.append('less than 4')
استخدام أكثر من if وelse
يمكن أيضاً بناء تعبير شرطي متعدد داخل List Comprehension. المثال التالي يوضح ذلك:
# with more than one if and else condition
f = ['Two' if x % 2 == 0 else 'Three' if x % 3 == 0 else 'not 2 & 3' for x in lst]
print(f)
# output ['not 2 & 3', 'Two', 'Three', 'Two', 'not 2 & 3', 'Two', 'not 2 & 3', 'Two', 'Three', 'Two']
التعبير الشرطي هنا هو:
'Two' if x % 2 == 0 else 'Three' if x % 3 == 0 else 'not 2 & 3'
آلية العمل كالتالي:
- إذا كانت
xتقبل القسمة على2، تكون النتيجة'Two'. - إذا لم يتحقق الشرط الأول، ينتقل إلى الشرط الثاني: هل تقبل
xالقسمة على3؟ إذا نعم، تكون النتيجة'Three'. - إذا لم يتحقق أي شرط، تُعاد القيمة
'not 2 & 3'.
والصيغة التقليدية المكافئة تشبه استخدام elif:
f = []
for x in lst:
if x % 2 == 0:
f.append('Two')
elif x % 3 == 0:
f.append('Three')
else:
f.append('not 2 & 3')
هذا مثال جيد على قوة List Comprehension، لكنه في الوقت نفسه يوضح ضرورة التوازن بين الاختصار والوضوح. إذا شعرت أن السطر الواحد أصبح مربكاً، فالحل التقليدي يكون أفضل.
استخدام حلقة for متداخلة داخل List Comprehension
يمكنك أيضاً كتابة حلقات for متداخلة باستخدام List Comprehension. وهذا مفيد عند إنشاء تراكيب أو أزواج أو جميع الاحتمالات الممكنة بين قائمتين.
lst = [1, 2, 3]
lst_rev = [3, 2, 1]
g = [(x, y) for x in lst for y in lst_rev]
print(g)
# output [(1, 3), (1, 2), (1, 1), (2, 3), (2, 2), (2, 1), (3, 3), (3, 2), (3, 1)]
في هذا المثال، يجري المرور على كل عنصر x في lst، ثم على كل عنصر y في lst_rev، وبعد ذلك يُحفظ الزوج (x, y) في القائمة الناتجة.
ويمكن كتابة ذلك بالشكل التقليدي كما يلي:
g = []
for x in lst:
for y in lst_rev:
g.append((x, y))
هذا الأسلوب عملي جداً عند التعامل مع التوافيق، أو توليد أزواج القيم، أو تجهيز بيانات أولية لاختبارات وخوارزميات مختلفة.
مقارنة بين for loop وList Comprehension
في كثير من الحالات، تكون List Comprehension أكثر اختصاراً من حلقة for التقليدية، وغالباً أسهل قراءة عندما تكون المهمة مباشرة. كما أنها قد تقدم أداءً أفضل في بعض السيناريوهات، لأن Python يعالجها بكفاءة جيدة.
| المعيار | List Comprehension |
for loop |
|---|---|---|
| عدد الأسطر | أقل غالباً | أكثر |
| الوضوح في المهام البسيطة | ممتاز | جيد |
| المرونة في المنطق المعقد | محدودة | أفضل |
| الأداء | قد يكون أسرع في بعض الحالات | جيد لكنه أطول كتابة |
| سهولة الصيانة | ممتازة إذا كانت الشيفرة قصيرة | أفضل عند تعقيد الشروط |
الخلاصة هنا أن List Comprehension ليست بديلاً كاملاً عن حلقات for، بل أداة مناسبة لنوع محدد من المهام: المهام الواضحة، القصيرة، والمتكررة.
أهم فوائد List Comprehension
- الاختصار: تقلل عدد الأسطر المطلوبة لكتابة الشيفرة.
- وضوح النية: تبيّن بسرعة أنك تنشئ قائمة جديدة من بيانات موجودة.
- المرونة: تدعم التصفية والتحويل وإضافة الشروط.
- السرعة: قد تكون أسرع من استخدام
for loopفي بعض التطبيقات العملية. - الأسلوب البرمجي الأفضل في
Python: كثير من المطورين يعدّونها أكثر توافقاً مع روح اللغة عندما تُستخدم بشكل مناسب.
متى تستخدم List Comprehension ومتى تتجنبها؟
متى يُفضّل استخدامها؟
- عندما تريد إنشاء قائمة جديدة من كائن قابل للتكرار.
- عندما تكون العملية بسيطة، مثل التصفية أو التعديل أو التنسيق.
- عندما ترغب في إبقاء الشيفرة مختصرة وواضحة.
- عندما يكون الأداء مهماً ولو بشكل طفيف.
متى يُفضّل تجنبها؟
- إذا كانت الشروط كثيرة أو متداخلة بشكل يربك القارئ.
- إذا كانت العملية تتطلب خطوات متعددة ومعالجة معقدة.
- إذا أصبحت الشيفرة في سطر واحد لكنها فقدت الوضوح.
القاعدة الذهبية بسيطة: إذا جعلت List Comprehension الشيفرة أوضح، فاستخدمها. وإذا جعلتها أعقد، فعد إلى for loop.
نصائح عملية للمبتدئين عند كتابة List Comprehension
- ابدأ أولاً بكتابة الحل باستخدام
for loopالتقليدية. - بعد التأكد من صحة المنطق، حوّله إلى
List Comprehensionإذا كان ذلك سيحسن الوضوح. - لا تجمع أكثر من منطق معقد في سطر واحد.
- اختر أسماء متغيرات مفهومة مثل
itemأوnumأوvalue. - راجع الناتج دائماً باستخدام
print()أو أدوات الاختبار قبل اعتماد الشيفرة.
الخلاصة التقنية
تُعد List Comprehension من الأدوات الأساسية التي تمنح شيفرة Python طابعاً نظيفاً ومعبّراً، خصوصاً عند إنشاء القوائم أو تصفية البيانات أو تعديلها بخطوات بسيطة. قوتها الحقيقية لا تكمن في الاختصار فقط، بل في قدرتها على التعبير عن الفكرة بسرعة ووضوح. ومع ذلك، فإن الاستخدام الاحترافي لها يعتمد على الحكم السليم: استخدمها حين تعزز القراءة، وتجنبها حين تتحول إلى سطر ذكي ظاهرياً لكنه مرهق للفهم والصيانة.