Set Comprehension: إنشاء المجموعات بأناقة وكفاءة في Python

بعد أن تعلمت List Comprehension و Dictionary Comprehension، حان الوقت لاستكشاف Set Comprehension. المجموعات (Sets) في بايثون هي بنية بيانات قوية تخزن عناصر فريدة بدون تكرار، وتوفر عمليات رياضية سريعة مثل الاتحاد والتقاطع. Set Comprehension تجعل إنشاء هذه المجموعات أسهل وأكثر أناقة.

1. تعريف: ما هي Set Comprehension؟

Set Comprehension هي طريقة مختصرة وفعالة لإنشاء مجموعة (Set) جديدة من بيانات موجودة. تشبه List Comprehension، لكنها تستخدم الأقواس المعقوفة {} وتضمن أن جميع العناصر فريدة تلقائياً.

الصيغة العامة:
# الصيغة الأساسية
{expression for item in iterable}

# مع شرط
{expression for item in iterable if condition}

الفرق الرئيسي عن List Comprehension: المجموعات لا تحتوي على عناصر مكررة ولا تحافظ على الترتيب (في Python 3.7+ تحافظ على ترتيب الإدخال).

2. لماذا نستخدم Set Comprehension؟

Set Comprehension توفر مزايا عديدة:

  • إزالة التكرارات تلقائياً: لا حاجة لفحص يدوي للعناصر المكررة.
  • أداء سريع: البحث في المجموعات أسرع بكثير من القوائم (O(1) مقابل O(n)).
  • كود أنيق: سطر واحد بدلاً من عدة أسطر من الحلقات.
  • عمليات رياضية: سهولة إجراء الاتحاد، التقاطع، والفرق بين المجموعات.

3. أمثلة أساسية على Set Comprehension

أ) مثال بسيط: إنشاء مجموعة من الأرقام
basic_set_comprehension.py
# الطريقة التقليدية
numbers_set = set()
for i in range(1, 6):
    numbers_set.add(i * 2)
print(numbers_set)  # {2, 4, 6, 8, 10}

# Set Comprehension - أنيقة ومختصرة
numbers_set = {i * 2 for i in range(1, 6)}
print(numbers_set)  # {2, 4, 6, 8, 10}
النتيجة
{2, 4, 6, 8, 10} {2, 4, 6, 8, 10}
ب) إزالة التكرارات من قائمة

واحدة من أكثر الاستخدامات شيوعاً لـ Set Comprehension هي إزالة العناصر المكررة:

remove_duplicates.py
# قائمة بها تكرارات
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5]

# إزالة التكرارات باستخدام Set Comprehension
unique_numbers = {num for num in numbers}
print(unique_numbers)  # {1, 2, 3, 4, 5}

# يمكن أيضاً تطبيق عملية على العناصر
squared_unique = {num ** 2 for num in numbers}
print(squared_unique)  # {1, 4, 9, 16, 25}
النتيجة
{1, 2, 3, 4, 5} {1, 4, 9, 16, 25}
ج) معالجة النصوص
text_processing.py
# استخراج الأحرف الفريدة من نص
text = "مرحبا بك في عالم البرمجة"
unique_chars = {char for char in text if char != ' '}
print(unique_chars)

# تحويل الكلمات إلى أحرف كبيرة
words = ["مرحبا", "عالم", "مرحبا", "بايثون", "عالم"]
unique_words = {word.upper() for word in words}
print(unique_words)  # {'مرحبا', 'عالم', 'بايثون'}
النتيجة
{'م', 'ر', 'ح', 'ب', 'ا', 'ك', 'ف', 'ي', 'ع', 'ل', 'ة', 'ن', 'ج'} {'مرحبا', 'عالم', 'بايثون'}

4. Set Comprehension مع الشروط

يمكنك إضافة شروط لفلترة العناصر قبل إضافتها للمجموعة:

أ) فلترة الأرقام
filtering_numbers.py
# الأرقام الزوجية فقط
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 4, 6]
even_numbers = {num for num in numbers if num % 2 == 0}
print(even_numbers)  # {2, 4, 6, 8, 10}

# الأرقام الأكبر من 5
large_numbers = {num for num in numbers if num > 5}
print(large_numbers)  # {6, 7, 8, 9, 10}

# مربعات الأرقام الفردية
odd_squares = {num ** 2 for num in numbers if num % 2 != 0}
print(odd_squares)  # {1, 9, 25, 49, 81}
النتيجة
{2, 4, 6, 8, 10} {6, 7, 8, 9, 10} {1, 9, 25, 49, 81}
ب) فلترة النصوص
filtering_text.py
# الكلمات الطويلة (أكثر من 4 أحرف)
words = ["مرحبا", "بك", "في", "عالم", "البرمجة", "مع", "بايثون"]
long_words = {word for word in words if len(word) > 4}
print(long_words)  # {'مرحبا', 'البرمجة', 'بايثون'}

# الكلمات التي تبدأ بحرف معين
words_with_b = {word for word in words if word.startswith('ب')}
print(words_with_b)  # {'بك', 'بايثون'}
النتيجة
{'مرحبا', 'البرمجة', 'بايثون'} {'بك', 'بايثون'}

5. أمثلة عملية متقدمة

أ) استخراج البيانات الفريدة من قوائم متداخلة
nested_lists.py
# قوائم متداخلة
matrix = [
    [1, 2, 3],
    [2, 3, 4],
    [3, 4, 5]
]

# استخراج جميع الأرقام الفريدة
unique_numbers = {num for row in matrix for num in row}
print(unique_numbers)  # {1, 2, 3, 4, 5}

# الأرقام الزوجية الفريدة فقط
even_unique = {num for row in matrix for num in row if num % 2 == 0}
print(even_unique)  # {2, 4}
النتيجة
{1, 2, 3, 4, 5} {2, 4}
ب) معالجة بيانات الطلاب
students_data.py
# بيانات الطلاب
students = [
    {"name": "أحمد", "grade": 85, "city": "القاهرة"},
    {"name": "فاطمة", "grade": 92, "city": "الرياض"},
    {"name": "محمد", "grade": 78, "city": "القاهرة"},
    {"name": "علي", "grade": 88, "city": "دبي"},
    {"name": "سارة", "grade": 95, "city": "الرياض"}
]

# استخراج المدن الفريدة
cities = {student["city"] for student in students}
print(cities)  # {'القاهرة', 'الرياض', 'دبي'}

# أسماء الطلاب الناجحين (درجة >= 85)
passing_students = {student["name"] for student in students if student["grade"] >= 85}
print(passing_students)  # {'أحمد', 'فاطمة', 'علي', 'سارة'}

# الدرجات الفريدة
unique_grades = {student["grade"] for student in students}
print(unique_grades)  # {78, 85, 88, 92, 95}
النتيجة
{'القاهرة', 'الرياض', 'دبي'} {'أحمد', 'فاطمة', 'علي', 'سارة'} {78, 85, 88, 92, 95}
ج) تحليل البيانات النصية
text_analysis.py
# تحليل نص
text = "Python is a powerful programming language. Python is easy to learn."
words = text.lower().replace('.', '').split()

# الكلمات الفريدة
unique_words = {word for word in words}
print(f"عدد الكلمات الفريدة: {len(unique_words)}")
print(unique_words)

# الكلمات الطويلة (أكثر من 5 أحرف)
long_words = {word for word in words if len(word) > 5}
print(f"الكلمات الطويلة: {long_words}")

# الأحرف الفريدة في النص
unique_chars = {char for word in words for char in word}
print(f"عدد الأحرف الفريدة: {len(unique_chars)}")
النتيجة
عدد الكلمات الفريدة: 9 {'python', 'is', 'a', 'powerful', 'programming', 'language', 'easy', 'to', 'learn'} الكلمات الطويلة: {'powerful', 'programming', 'language'} عدد الأحرف الفريدة: 18

6. عمليات المجموعات مع Set Comprehension

يمكنك دمج Set Comprehension مع العمليات الرياضية على المجموعات:

set_operations.py
# مجموعتان
set_a = {1, 2, 3, 4, 5}
set_b = {4, 5, 6, 7, 8}

# الاتحاد (Union) - جميع العناصر
union = {x for x in set_a} | {x for x in set_b}
print(f"الاتحاد: {union}")  # {1, 2, 3, 4, 5, 6, 7, 8}

# التقاطع (Intersection) - العناصر المشتركة
intersection = {x for x in set_a if x in set_b}
print(f"التقاطع: {intersection}")  # {4, 5}

# الفرق (Difference) - العناصر في A وليست في B
difference = {x for x in set_a if x not in set_b}
print(f"الفرق: {difference}")  # {1, 2, 3}

# الفرق المتماثل (Symmetric Difference) - العناصر في واحدة فقط
sym_diff = {x for x in set_a if x not in set_b} | {x for x in set_b if x not in set_a}
print(f"الفرق المتماثل: {sym_diff}")  # {1, 2, 3, 6, 7, 8}
النتيجة
الاتحاد: {1, 2, 3, 4, 5, 6, 7, 8} التقاطع: {4, 5} الفرق: {1, 2, 3} الفرق المتماثل: {1, 2, 3, 6, 7, 8}

7. أخطاء شائعة يجب تجنبها

خطأ 1: محاولة إضافة عناصر قابلة للتغيير

المجموعات لا يمكنها احتواء عناصر قابلة للتغيير مثل القوائم أو القواميس:

# خطأ - لا يمكن إضافة قوائم للمجموعة
# lists = {[1, 2], [3, 4]}  # TypeError

# الحل: استخدم tuples بدلاً من lists
tuples_set = {(1, 2), (3, 4)}
print(tuples_set)  # {(1, 2), (3, 4)}
خطأ 2: الخلط بين {} الفارغة والمجموعة

{} تنشئ قاموساً فارغاً وليس مجموعة فارغة:

# خطأ شائع
empty = {}
print(type(empty))  # 

# الصحيح - لإنشاء مجموعة فارغة
empty_set = set()
print(type(empty_set))  # 

# Set Comprehension تنشئ مجموعة تلقائياً
numbers_set = {x for x in range(5)}
print(type(numbers_set))  # 
خطأ 3: توقع ترتيب معين

المجموعات غير مرتبة (في Python 3.7+ تحافظ على ترتيب الإدخال لكن لا تضمن ذلك):

# لا تعتمد على الترتيب
numbers = {5, 1, 3, 2, 4}
print(numbers)  # قد يطبع بترتيب مختلف

# إذا كنت بحاجة للترتيب، حول إلى قائمة
sorted_numbers = sorted(numbers)
print(sorted_numbers)  # [1, 2, 3, 4, 5]

8. نصائح مهمة وأفضل الممارسات

  • استخدم Set Comprehension لإزالة التكرارات: أسرع وأنظف من الطرق الأخرى.
  • اختر المجموعات للبحث السريع: البحث في المجموعات O(1) مقابل O(n) في القوائم.
  • تجنب المجموعات للبيانات المرتبة: استخدم القوائم إذا كان الترتيب مهماً.
  • استخدم frozenset للمجموعات الثابتة: يمكن استخدامها كمفاتيح في القواميس.
  • اجمع بين Set Comprehension والعمليات الرياضية: لمعالجة بيانات معقدة بكفاءة.
مثال: مقارنة الأداء
performance_comparison.py
import time

# بيانات كبيرة مع تكرارات
data = list(range(100000)) * 3  # 300,000 عنصر

# الطريقة 1: باستخدام list ثم set
start = time.time()
unique_list = []
for item in data:
    if item not in unique_list:
        unique_list.append(item)
time1 = time.time() - start

# الطريقة 2: Set Comprehension
start = time.time()
unique_set = {item for item in data}
time2 = time.time() - start

print(f"الطريقة التقليدية: {time1:.4f} ثانية")
print(f"Set Comprehension: {time2:.4f} ثانية")
print(f"Set Comprehension أسرع بـ {time1/time2:.0f}x")
النتيجة (تقريبية)
الطريقة التقليدية: 45.2341 ثانية Set Comprehension: 0.0123 ثانية Set Comprehension أسرع بـ 3677x

9. تمرين عملي

التحدي: تحليل بيانات المبيعات

لديك قائمة بمعاملات المبيعات. استخدم Set Comprehension لاستخراج المعلومات التالية:

sales = [
    {"product": "Laptop", "category": "Electronics", "price": 1200},
    {"product": "Mouse", "category": "Electronics", "price": 25},
    {"product": "Desk", "category": "Furniture", "price": 300},
    {"product": "Chair", "category": "Furniture", "price": 150},
    {"product": "Monitor", "category": "Electronics", "price": 400},
    {"product": "Keyboard", "category": "Electronics", "price": 75},
]

# المطلوب:
# 1. جميع الفئات الفريدة
# 2. أسماء المنتجات التي سعرها أكثر من 100
# 3. الأسعار الفريدة
# 4. الفئات التي تحتوي على منتجات سعرها أقل من 200

تلميح: استخدم Set Comprehension مع الشروط المناسبة!

ملخص الدرس
  • Set Comprehension تستخدم الأقواس المعقوفة {} لإنشاء مجموعات.
  • المجموعات تحتوي على عناصر فريدة فقط بدون تكرار.
  • البحث في المجموعات أسرع بكثير من القوائم (O(1) vs O(n)).
  • يمكن استخدام الشروط لفلترة العناصر قبل إضافتها.
  • المجموعات لا يمكنها احتواء عناصر قابلة للتغيير مثل القوائم.
  • {} الفارغة تنشئ قاموساً، استخدم set() للمجموعة الفارغة.
  • Set Comprehension مثالية لإزالة التكرارات وإجراء العمليات الرياضية.

الخطوة التالية

الآن بعد أن أتقنت Set Comprehension، حان الوقت لتعلم الدوال المجهولة التي ستجعل كودك أكثر مرونة وقوة.

الدرس التالي: الدوال المجهولة (Lambda Functions)
المحرر الذكي

اكتب الكود وشاهد النتيجة فوراً

جرب الآن مجاناً
قناة ديف عربي

تابع أحدث الدروس والتحديثات مباشرة على واتساب

انضم الآن