شرح List Comprehension في بايثون بالأمثلة للمبتدئين

شرح List Comprehension في Python للمبتدئين لإنشاء القوائم المختصرة بدل for loop

إذا كنت تبحث عن شرح List Comprehension في بايثون، فالفكرة الأساسية بسيطة: هي صياغة مدمجة لإنشاء List جديدة من عناصر iterable مثل قائمة أو range() أو نص، مع إمكانية تحويل العناصر أو تصفيتها بشرط.

بدل كتابة قائمة فارغة ثم حلقة for ثم append() في عدة أسطر، تستطيع في الحالات البسيطة التعبير عن الفكرة نفسها داخل الأقواس المربعة []. لكن الاختصار ليس الهدف الوحيد؛ الأهم أن يبقى الكود واضحًا وسهل القراءة.

في هذا الدرس سنبدأ بالمقارنة مع for loop، ثم نشرح الصيغة الأساسية، واستخدام if للتصفية، والفرق بين التصفية وكتابة if/else داخل التعبير، مع أمثلة وأخطاء شائعة للمبتدئين.

{getToc} $title={محتوى المقال}

{alertInfo} الخلاصة السريعة: استخدم List Comprehension عندما تريد إنشاء قائمة جديدة من تكرار بسيط وواضح. إذا أصبح الشرط أو التحويل طويلًا، فحلقة for العادية غالبًا أوضح.

قبل المتابعة، يفيد أن تكون مرتاحًا مع القوائم Lists في بايثون و حلقات for وwhile.

شرح الصيغة الأساسية لـ List Comprehension في Python باستخدام expression و for و iterable

ما هي List Comprehension في بايثون؟

توثيق بايثون يصف List Comprehension بأنها طريقة مختصرة لإنشاء قوائم جديدة، سواء بتطبيق عملية على كل عنصر من Iterable أو باختيار العناصر التي تحقق شرطًا معينًا.

لنبدأ بمثال بسيط: نريد إنشاء قائمة بالأرقام من 0 إلى 4. بالطريقة التقليدية:

numbers = []\n\nfor i in range(5):\n    numbers.append(i)\n\nprint(numbers)

الناتج:

[0, 1, 2, 3, 4]

وباستخدام List Comprehension:

numbers = [i for i in range(5)]\nprint(numbers)

الناتج نفسه:

[0, 1, 2, 3, 4]

هنا أنشأنا قائمة جديدة مباشرة. هذه نقطة مهمة: List Comprehension ليست طريقة لتعديل القائمة الأصلية في مكانها، بل تعيد List جديدة.

الصيغة الأساسية لـ List Comprehension

new_list = [expression for item in iterable]

اقرأها بهذا الترتيب:

  • for item in iterable: مرّ على كل عنصر.
  • expression: حدد القيمة التي ستوضع في القائمة الجديدة.
  • []: النتيجة النهائية List جديدة.

مثلًا لإنشاء مربعات الأرقام من 1 إلى 5:

squares = [number ** 2 for number in range(1, 6)]\nprint(squares)

الناتج:

[1, 4, 9, 16, 25]
مثال إنشاء قائمة مربعات الأرقام في Python باستخدام List Comprehension بدل append داخل for loop

List Comprehension مقابل for loop

المثال السابق يمكن كتابته أيضًا بهذه الصورة:

squares = []\n\nfor number in range(1, 6):\n    squares.append(number ** 2)

النسختان صحيحتان. اختر List Comprehension عندما تكون العملية قصيرة وواضحة، واستخدم for العادية عندما تحتاج أكثر من خطوة أو أكثر من أمر داخل كل دورة.

الحالة for loop List Comprehension
إنشاء قائمة بتحويل بسيط صحيحة لكن أطول غالبًا مناسبة جدًا
تصفية شرط بسيط واضحة مختصرة وواضحة غالبًا
عدة أوامر داخل كل دورة أفضل عادةً قد تصبح مربكة
شروط متداخلة كثيرة أسهل للقراءة لا تختصر على حساب الوضوح

استخدام if للتصفية داخل List Comprehension

إذا أردت أخذ بعض العناصر فقط، أضف if بعد جزء for.

even_numbers = [number for number in range(1, 11) if number % 2 == 0]\nprint(even_numbers)

الناتج:

[2, 4, 6, 8, 10]

الشرط هنا يقرر هل يدخل العنصر إلى القائمة أم لا. الرقم الذي لا يحقق الشرط يُستبعد.

استخدام if داخل List Comprehension في Python لاستخراج الأرقام الزوجية من 1 إلى 10

الفرق بين if للتصفية و if/else لاختيار القيمة

هذه من أهم النقاط التي تسبب الحيرة للمبتدئ. توجد حالتان مختلفتان:

1. if للتصفية

positive = [number for number in [-2, -1, 0, 1, 2] if number > 0]\nprint(positive)

الناتج:

[1, 2]

هنا العناصر غير المطابقة اختفت من القائمة.

2. if/else لاختيار قيمة لكل عنصر

إذا أردت الاحتفاظ بكل العناصر لكن تغيير القيمة حسب الشرط، تأتي صيغة if/else في بداية التعبير:

labels = ["even" if number % 2 == 0 else "odd" for number in range(1, 6)]\nprint(labels)

الناتج:

['odd', 'even', 'odd', 'even', 'odd']
{alertWarning} لا تخلط بين الصيغتين: التصفية تكون عادةً [expression for item in iterable if condition]، أما الاختيار بين قيمتين فيكون [value_if_true if condition else value_if_false for item in iterable].

ولفهم الشروط نفسها بصورة أعمق، راجع شرح if وelse وelif في بايثون.

تعديل القيم أثناء إنشاء القائمة

ليس مطلوبًا أن تضيف العنصر كما هو. يمكنك استدعاء دالة أو Method أو إجراء عملية حسابية عليه.

names = ["ahmed", "sara", "omar"]\nupper_names = [name.upper() for name in names]\nprint(upper_names)

الناتج:

['AHMED', 'SARA', 'OMAR']

استخدام List Comprehension مع النصوص

النص نفسه Iterable، ولذلك يمكنك المرور على حروفه:

letters = [letter for letter in "Python"]\nprint(letters)

الناتج:

['P', 'y', 't', 'h', 'o', 'n']

ويمكنك دمجها مع split() لمعالجة الكلمات:

text = "python is easy"\nwords = [word.capitalize() for word in text.split()]\nprint(words)

الناتج:

['Python', 'Is', 'Easy']

إذا أردت فهم split() وlen() بصورة عملية، راجع حساب عدد الكلمات في نص باستخدام بايثون.

مثال عملي: استخراج الكلمات الطويلة

text = "Python is a powerful programming language"\nlong_words = [word for word in text.split() if len(word) > 4]\nprint(long_words)

الناتج:

['Python', 'powerful', 'programming', 'language']

لاحظ أن word في البداية هي القيمة التي نريد الاحتفاظ بها، بينما الشرط في النهاية يحدد الكلمات التي ستدخل إلى القائمة.

هل يمكن استخدام أكثر من for أو if؟

نعم، تسمح الصياغة بأكثر من جملة for أو if. مثلًا:

pairs = [(x, y) for x in [1, 2] for y in [10, 20]]\nprint(pairs)

الناتج:

[(1, 10), (1, 20), (2, 10), (2, 20)]

لكن لا تجعل هذا سببًا لكتابة تعبيرات طويلة جدًا. في الأمثلة المتداخلة، اقرأ أجزاء for وif بالترتيب نفسه الذي ستكتبه في الحلقات العادية.

متى لا تستخدم List Comprehension؟

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

بدل كتابة منطق كثيف داخل سطر واحد، قد تكون هذه الصورة أوضح:

result = []\n\nfor number in range(20):\n    if number > 5 and number % 2 == 0:\n        result.append(number * 2)\n\nprint(result)
{alertSuccess} القاعدة العملية: List Comprehension مناسبة لإنشاء قائمة جديدة عندما تستطيع فهم التعبير بسرعة. إذا احتجت إلى تفكيك السطر ذهنيًا عدة مرات، فاكتب for loop عادية.

هل List Comprehension أسرع من for loop؟

قد تكون List Comprehension أسرع في بعض الحالات البسيطة مقارنة بحلقة تبني القائمة عبر append()، لكن لا تجعل الأداء سببك الأول لاختيارها في كود المبتدئين. الفارق يعتمد على العملية والبيانات، والوضوح أهم ما لم تكن قد قست أداء حالة حقيقية.

كذلك تذكّر أنها تنشئ List كاملة في الذاكرة. إذا كنت تتعامل مع كمية ضخمة من البيانات ولا تحتاج القائمة كاملة مرة واحدة، فهذه مسألة مختلفة عن هدف هذا الدرس.

الفرق بين List Comprehension وGenerator Expression

هذه الصيغتان تبدوان متشابهتين لكن النتيجة مختلفة:

numbers_list = [x * 2 for x in range(5)]\nnumbers_generator = (x * 2 for x in range(5))\n\nprint(type(numbers_list))\nprint(type(numbers_generator))

الأقواس المربعة [] تنشئ list، بينما الأقواس الدائرية في الصيغة الثانية تنشئ Generator Expression. لا نحتاج إلى تفاصيل Generators الآن؛ المهم ألا تتوقع List إذا استخدمت الأقواس الدائرية.

أخطاء شائعة في List Comprehension

  • نسيان الأقواس المربعة: إذا كنت تريد List Comprehension فالصيغة يجب أن تكون داخل [].
  • الخلط بين التصفية وif/else: مكان الشرط يختلف حسب هل تريد حذف عناصر أم اختيار قيمة بديلة.
  • نسيان التعبير في البداية: تحتاج قيمة تُضاف إلى القائمة، مثل x أو x * 2.
  • حشر منطق معقد في سطر واحد: الاختصار الذي يقلل الوضوح ليس تحسينًا.
  • استخدامها لمجرد تنفيذ side effects: إذا كان هدفك فقط تشغيل print() أو تعديل أشياء خارجية، فحلقة for العادية أوضح عادةً.

مثال نهائي يجمع التحويل والتصفية

numbers = [1, 2, 3, 4, 5, 6]\nresult = [number * 2 for number in numbers if number % 2 == 0]\nprint(result)

الناتج:

[4, 8, 12]

ما حدث هو: مررنا على القائمة، اخترنا الأرقام الزوجية فقط، ثم ضربنا كل رقم مقبول في 2 ووضعناه في List جديدة.

مقارنة بين for loop و List Comprehension في Python من حيث عدد الأسطر والوضوح والاستخدام المناسب

تمرين على List Comprehension

لديك القائمة التالية:

numbers = [1, 2, 3, 4, 5]

أنشئ باستخدام List Comprehension قائمة جديدة تحتوي على مربع كل رقم. النتيجة المطلوبة:

[1, 4, 9, 16, 25]

ثم جرّب تمرينًا ثانيًا: أنشئ قائمة تحتوي فقط على الأرقام الأكبر من 2، وبعدها قارن حلك بتمارين Lists في بايثون مع الحلول.

أسئلة شائعة

هل List Comprehension بديل عن for loop؟

لا. هي صياغة مناسبة لبعض حالات إنشاء القوائم، لكن for loop أوسع وتبقى أفضل عندما تحتاج منطقًا متعدد الخطوات.

هل يمكن استخدام if داخل List Comprehension؟

نعم. يمكنك استخدامها في النهاية لتصفية العناصر، مثل [x for x in items if condition].

هل يمكن استخدام if وelse معًا؟

نعم، عندما تريد اختيار قيمة لكل عنصر، مثل [a if condition else b for x in items]. هذه الصيغة تختلف عن شرط التصفية.

هل List Comprehension تعدل القائمة الأصلية؟

لا. النتيجة هي قائمة جديدة. قد تستخدم عناصر من القائمة الأصلية، لكن الصياغة نفسها تنشئ List جديدة.

هل يمكن أن تحتوي على أكثر من for؟

نعم، ويمكن أن تحتوي على عدة جمل for أو if، لكن من الأفضل تجنب التعقيد الذي يجعل القراءة أصعب.

روابط مفيدة من بايثون العرب

الخلاصة

List Comprehension في بايثون طريقة مدمجة لإنشاء قائمة جديدة من Iterable. الصيغة الأساسية هي [expression for item in iterable]، ويمكن إضافة شرط تصفية في النهاية أو استخدام تعبير if/else لاختيار قيمة مختلفة لكل عنصر.

لا تجعل عدد الأسطر هو معيارك الوحيد. استخدم List Comprehension عندما تجعل الفكرة أوضح وأقصر، وانتقل إلى for loop عندما يصبح المنطق طويلًا أو متعدد الخطوات.

{alertSuccess} الخلاصة السريعة: افهم for loop أولًا، ثم استخدم List Comprehension لإنشاء القوائم عندما تكون العملية قصيرة وواضحة.

إرسال تعليق

أحدث أقدم