قائمة البرمجية (List Comprehension): إنشاء القوائس بأناقة وكفاءة
حتى الآن، استخدمت حلقات for لإنشاء قوائس جديدة أو تعديل البيانات. لكن Python توفر طريقة أكثر أناقة وكفاءة تسمى List Comprehension (القائمة البرمجية). هذه الطريقة تجعل الكود أقصر وأسهل قراءة وأسرع أداءً. ستتعلم اليوم كيفية استخدام هذه الأداة القوية لكتابة كود احترافي.
1. ما هي List Comprehension؟
List Comprehension هي طريقة مختصرة لإنشاء قائمة جديدة من قائمة موجودة بتطبيق عملية معينة على كل عنصر. بدلاً من كتابة حلقة طويلة، تستطيع كتابة سطر واحد!
مقارنة: الطريقة التقليدية vs List Comprehension
# الطريقة التقليدية - طويلة وممله
numbers = [1, 2, 3, 4, 5]
squared = []
for num in numbers:
squared.append(num ** 2)
print(squared) # [1, 4, 9, 16, 25]
# List Comprehension - أنيقة وفعالة
numbers = [1, 2, 3, 4, 5]
squared = [num ** 2 for num in numbers]
print(squared) # [1, 4, 9, 16, 25]
نفس النتيجة، لكن الكود الثاني أقصر وأوضح!
الصيغة الأساسية:
# الصيغة الأساسية:
# [output for item in iterable]
# مثال بسيط
result = [x * 2 for x in range(1, 6)]
print(result) # [2, 4, 6, 8, 10]
# مثال مع نص
words = ["مرحبا", "عالم", "بايثون"]
upper_words = [word.upper() for word in words]
print(upper_words) # ['مرحبا', 'عالم', 'بايثون']
2. List Comprehension مع الشروط (Filtering)
يمكنك إضافة شرط if لفلترة العناصر والاحتفاظ بالعناصر التي تطابق الشرط فقط.
الصيغة مع الشرط:
# الصيغة:
# [output for item in iterable if condition]
# مثال: الأرقام الزوجية فقط
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = [num for num in numbers if num % 2 == 0]
print(evens) # [2, 4, 6, 8, 10]
# مثال: الكلمات التي تبدأ بـ 'أ'
words = ["أحمد", "علي", "أسد", "فاطمة", "أمل"]
a_words = [word for word in words if word[0] == 'أ']
print(a_words) # ['أحمد', 'أسد', 'أمل']
مثال متقدم: Filtering و Transformation معاً
# الأرقام الزوجية مرفوعة للقوة 2
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = [num ** 2 for num in numbers if num % 2 == 0]
print(result) # [4, 16, 36, 64, 100]
# الكلمات الطويلة (أكثر من 5 حروف) بأحرف كبيرة
words = ["مرحبا", "عالم", "بايثون", "برمجة", "حاسوب"]
result = [word.upper() for word in words if len(word) > 5]
print(result) # ['بايثون']
3. List Comprehension المتعددة الحلقات (Nested)
يمكنك استخدام حلقات متعددة داخل List Comprehension لإنشاء بيانات معقدة بسهولة.
مثال: جدول الضرب
# جدول الضرب - الطريقة التقليدية
table = []
for i in range(1, 4):
for j in range(1, 4):
table.append(i * j)
print(table) # [1, 2, 3, 2, 4, 6, 3, 6, 9]
# جدول الضرب - List Comprehension
table = [i * j for i in range(1, 4) for j in range(1, 4)]
print(table) # [1, 2, 3, 2, 4, 6, 3, 6, 9]
# نسخة أفضل: جدول مصفوفة
table = [[i * j for j in range(1, 4)] for i in range(1, 4)]
print(table) # [[1, 2, 3], [2, 4, 6], [3, 6, 9]]
مثال: توليد أزواج
# توليد أزواج من قائمتين
boys = ["أحمد", "محمد", "علي"]
girls = ["فاطمة", "سارة", "ليلى"]
pairs = [(boy, girl) for boy in boys for girl in girls]
print(len(pairs)) # 9 أزواج
print(pairs[0]) # ('أحمد', 'فاطمة')
4. List Comprehension مع if-else
يمكنك استخدام if-else لتعديل قيمة العناصر بدلاً من فلترتها.
الفرق بين if و if-else:
# if وحده - يفلتر العناصر
numbers = [1, 2, 3, 4, 5]
result = [x for x in numbers if x % 2 == 0]
print(result) # [2, 4] - حذفنا الفردية
# if-else - يعدل القيمة
numbers = [1, 2, 3, 4, 5]
result = [x if x % 2 == 0 else 0 for x in numbers]
print(result) # [0, 2, 0, 4, 0] - بدلنا الفردية بـ 0
أمثلة عملية:
# تصنيف الطلاب حسب الدرجات
grades = [45, 75, 92, 55, 88, 40]
result = ["نجح" if g >= 60 else "راسب" for g in grades]
print(result)
# ['راسب', 'نجح', 'نجح', 'راسب', 'نجح', 'راسب']
# تحويل النصوص حسب الطول
words = ["أ", "مرحبا", "بايثون"]
result = [word.upper() if len(word) > 2 else word for word in words]
print(result) # ['أ', 'مرحبا', 'بايثون']
5. Dictionary و Set Comprehension
نفس فكرة List Comprehension تعمل مع Dictionaries و Sets أيضاً!
Dictionary Comprehension:
# الصيغة: {key: value for item in iterable}
# مثال 1: مربع الأرقام
numbers = [1, 2, 3, 4, 5]
squares = {num: num ** 2 for num in numbers}
print(squares)
# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# مثال 2: تحويل قائمة إلى قاموس
words = ["مرحبا", "عالم", "بايثون"]
word_lengths = {word: len(word) for word in words}
print(word_lengths)
# {'مرحبا': 5, 'عالم': 5, 'بايثون': 6}
# مثال 3: مع شرط
numbers = [1, 2, 3, 4, 5]
evens = {num: num ** 2 for num in numbers if num % 2 == 0}
print(evens) # {2: 4, 4: 16}
Set Comprehension:
# الصيغة: {expression for item in iterable}
# مثال 1: إزالة العناصر المكررة
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique = {num for num in numbers}
print(unique) # {1, 2, 3, 4}
# مثال 2: مربع الأرقام الفريدة
numbers = [1, 2, 2, 3, 3, 4]
squared = {num ** 2 for num in numbers}
print(squared) # {1, 4, 9, 16}
# مثال 3: مع شرط
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
evens = {num for num in numbers if num % 2 == 0}
print(evens) # {2, 4, 6, 8}
6. أمثلة عملية واقعية
مثال 1: معالجة بيانات الطلاب
# بيانات الطلاب
students = [
{"name": "أحمد", "grade": 85},
{"name": "فاطمة", "grade": 92},
{"name": "محمد", "grade": 78},
{"name": "علي", "grade": 88}
]
# استخراج أسماء الطلاب الناجحين
passing = [s["name"] for s in students if s["grade"] >= 80]
print(passing) # ['أحمد', 'فاطمة', 'علي']
# إضافة 5 نقاط للدرجات
boosted = [{**s, "grade": s["grade"] + 5} for s in students]
for s in boosted:
print(f"{s['name']}: {s['grade']}")
مثال 2: معالجة النصوص
# النص
text = "مرحبا بك في عالم البرمجة"
words = text.split()
# الكلمات الطويلة (أكثر من 4 حروف)
long_words = [w for w in words if len(w) > 4]
print(long_words) # ['مرحبا', 'البرمجة']
# الكلمات بأحرف كبيرة
upper_words = [w.upper() for w in words]
print(" ".join(upper_words))
# مرحبا بك في عالم البرمجة
# قاموس: الكلمة وطولها
word_len = {w: len(w) for w in words}
print(word_len)
# {'مرحبا': 5, 'بك': 2, 'في': 2, 'عالم': 4, 'البرمجة': 6}
مثال 3: تحويل البيانات
# قائمة أسعار
prices = [10, 20, 30, 40, 50]
# حساب السعر بعد خصم 20%
discounted = [p * 0.8 for p in prices]
print(discounted)
# [8.0, 16.0, 24.0, 32.0, 40.0]
# تحويل إلى أسعار صحيحة
final_prices = [int(p * 0.8) for p in prices]
print(final_prices) # [8, 16, 24, 32, 40]
# قاموس: السعر الأصلي والمخفف
price_dict = {f"السعر_{i+1}": {"أصلي": p, "مخفف": int(p*0.8)}
for i, p in enumerate(prices)}
print(price_dict)
7. الأداء والمقارنة
List Comprehension أسرع من الحلقات العادية لأنها مُحسّنة من قبل Python!
import time
# الحلقة التقليدية
start = time.time()
result1 = []
for i in range(1000000):
result1.append(i ** 2)
time1 = time.time() - start
# List Comprehension
start = time.time()
result2 = [i ** 2 for i in range(1000000)]
time2 = time.time() - start
print(f"الحلقة التقليدية: {time1:.4f} ثانية")
print(f"List Comprehension: {time2:.4f} ثانية")
print(f"الفرق: {time1/time2:.2f}x أسرع")
8. الأخطاء الشائعة
الخطأ 1: الخلط بين if (تصفية) و if-else (تحويل)
# الخطأ: هذا سيحدث SyntaxError
# result = [x if x % 2 == 0 for x in range(5)]
# الصحيح - استخدم if-else إذا أردت if في البداية
result = [x if x % 2 == 0 else -x for x in range(5)]
print(result) # [0, -1, 2, -3, 4]
الخطأ 2: Nested comprehension معقد جداً
# سيء: معقد جداً
result = [[y if y % 2 == 0 else -y for y in range(x)]
for x in range(5) if x % 2 == 1]
# جيد: استخدم دالة أو حلقة عادية
def process_list(x):
return [y if y % 2 == 0 else -y for y in range(x)]
result = [process_list(x) for x in range(5) if x % 2 == 1]
الخطأ 3: نسيان الشرط في Dictionary comprehension
# الخطأ: نسيان الشرط في المكان الصحيح
# d = {k: v for k, v in data if v > 10} # خطأ
# الصحيح
data = {"a": 5, "b": 15, "c": 20}
d = {k: v for k, v in data.items() if v > 10}
print(d) # {'b': 15, 'c': 20}
9. نصائح مهمة وأفضل الممارسات
- الوضوح أولاً: إذا كانت List Comprehension معقدة جداً، استخدم حلقة عادية
- استخدم الأقواس المعقوفة {} للقواموس والمجموعات: لا تخلط بينها
- استخدم الأقواس العادية () للمولدات (Generators): أكثر كفاءة في الذاكرة
- تجنب التعقيد المفرط: comprehension يجب أن تكون مفهومة بسرعة
- استخدم متغيرات واضحة: بدلاً من اختصارات صعبة الفهم
مثال: استخدام Generators (أكثر كفاءة)
# List Comprehension - تخزن جميع العناصر في الذاكرة
list_result = [x ** 2 for x in range(1000000)]
print(type(list_result)) #
# Generator expression - توليد واحد تلو الآخر (أقل استهلاك للذاكرة)
gen_result = (x ** 2 for x in range(1000000))
print(type(gen_result)) #
# الفرق:
# list_result يخزن 1000000 عنصر في الذاكرة
# gen_result يولد العناصر عند الطلب فقط
10. تمرين عملي شامل
قم بكتابة برنامج يقوم بالمهام التالية:
- أنشئ قائمة من أرقام من 1 إلى 100
- استخرج الأرقام الزوجية فقط باستخدام List Comprehension
- حسب مربع الأرقام الفردية
- أنشئ قاموس يحتوي على الأرقام ومربعاتها
- أنشئ مجموعة من جميع الأرقام التي تقبل القسمة على 5
تفكر متقدم: كيف يمكن دمج جميع هذه العمليات في comprehension واحد معقد؟
الخلاصة والانتقال إلى الفصل التالي
لقد تعلمت اليوم:
- أساسيات List Comprehension والفرق عن الحلقات العادية
- كيفية استخدام الشروط للفلترة والتحويل
- الحلقات المتعددة (Nested) في Comprehension
- Dictionary و Set Comprehension
- استخدام Generator expressions للكفاءة
- أمثلة عملية واقعية وشائعة الاستخدام
في الفصل التالي، ستتعلم عن البرمجة الموجهة للكائنات (OOP). هذا سيأخذ برمجتك إلى مستوى جديد تماماً، حيث ستتمكن من بناء برامج أكثر تعقيداً وتنظيماً.