Comprehensions — هياكل البيانات
Comprehensions
كثيراً ما نكتب حلقة هدفها الوحيد بناء قائمة جديدة من قائمة موجودة:
squares = []
for x in range(1, 6):
squares.append(x ** 2)الـ comprehension تكتب نفس الفكرة في سطر واحد مقروء:
squares = [x ** 2 for x in range(1, 6)]البنية
[ التعبير for العنصر in المصدر if الشرط ]
اقرأها هكذا: "أعطني التعبير لكل عنصر في المصدر يحقق الشرط".
evens = [n for n in range(20) if n % 2 == 0]
names = [s.title() for s in ["sara", "ali"]]if في المكانين
nums = [4, -2, 7, -1]
[x for x in nums if x > 0] # تصفية: if في النهاية
["موجب" if x > 0 else "سالب" for x in nums] # اختيار قيمة: if-else في البدايةالتصفية تحذف عناصر، أما if-else في البداية فتنتج عنصراً لكل عنصر.
أنواع أخرى
words = ["Python", "code", "python"]
{n: n ** 2 for n in range(5)} # قاموس
{w.lower() for w in words} # مجموعة
sum(x ** 2 for x in range(1000)) # تعبير مولّد (generator)تعبير المولّد بين أقواس عادية لا ينشئ القائمة في الذاكرة، بل ينتج القيم واحدة واحدة، لذلك هو الأنسب مع sum و max و any على بيانات كبيرة.
الحلقات المتداخلة
matrix = [[1, 2], [3, 4]]
pairs = [(x, y) for x in range(3) for y in range(3) if x != y]
flat = [n for row in matrix for n in row]الترتيب مثل الحلقات العادية: الأولى هي الخارجية.
متى لا تستخدمها؟
- إذا احتجت أكثر من شرط وتحويل معقد، الحلقة العادية أوضح.
- إذا كان الهدف تنفيذ فعل (طباعة، حفظ) وليس بناء قائمة، استخدم حلقة: [print(x) for x in items] أسلوب سيئ.
تمرين
من قائمة قواميس طلاب {"name", "score"}: أنشئ قائمة بأسماء الناجحين (≥ 50)، وقاموساً {الاسم: التقدير}، ومجموعة بالدرجات المختلفة.
# List Comprehension الأساسية
squares = [x**2 for x in range(1, 6)]
print(squares) # [1, 4, 9, 16, 25]
# مع شرط
evens = [x for x in range(10) if x % 2 == 0]
print(evens) # [0, 2, 4, 6, 8]
# مع تحويل
names = ["ahmed", "mohammed", "ali"]
upper_names = [name.upper() for name in names]
print(upper_names) # ['AHMED', 'MOHAMMED', 'ALI']
# Nested loops
matrix = [[1, 2], [3, 4], [5, 6]]
flat = [num for row in matrix for num in row]
print(flat) # [1, 2, 3, 4, 5, 6]
# مع if-else
labels = ["زوجي" if x % 2 == 0 else "فردي" for x in range(5)]
print(labels) # ['زوجي', 'فردي', 'زوجي', 'فردي', 'زوجي']
# Dict Comprehension
nums = [1, 2, 3, 4, 5]
squares_dict = {n: n**2 for n in nums}
print(squares_dict) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# عكس قاموس
original = {'a': 1, 'b': 2, 'c': 3}
flipped = {v: k for k, v in original.items()}
print(flipped) # {1: 'a', 2: 'b', 3: 'c'}
# Set Comprehension
text = "hello world"
unique_letters = {char for char in text if char.isalpha()}
print(unique_letters) # {'h', 'e', 'l', 'o', 'w', 'r', 'd'}
# Generator Expression (توفير الذاكرة)
sum_squares = sum(x**2 for x in range(1000000))
# مقارنة الذاكرة
import sys
list_comp = [x**2 for x in range(1000)]
gen_exp = (x**2 for x in range(1000))
print(f"List: {sys.getsizeof(list_comp)} bytes")
print(f"Generator: {sys.getsizeof(gen_exp)} bytes")
# تطبيق عملي: تصفية بيانات
students = [
{"name": "أحمد", "score": 85},
{"name": "محمد", "score": 45},
{"name": "علي", "score": 92},
]
passed = [s["name"] for s in students if s["score"] >= 60]
print(passed) # ['أحمد', 'علي']اختبر فهمك