مقارنة الحاويات والشاملات الشاملة

غطينا القوائم والصفوف والقواميس والمجموعات بشكل فردي. الآن دعنا نقوم بمقارنة جنباً إلى جنب — ما هي الاختلافات، ومتى يجب استخدام كل منها؟ سنتقن أيضاً الشاملات، واحدة من أقوى ميزات بايثون.


1. مقارنة الحاويات الأربع

الميزة قائمة (list) صف (tuple) قاموس (dict) مجموعة (set)
الصيغة [] () {key: value} {} أو set()
مرتبة ✅ نعم ✅ نعم ✅ ترتيب الإدراج (3.7+) ❌ غير مرتبة
قابلة للتعديل
التكرارات ✅ مسموح ✅ مسموح المفاتيح فريدة، القيم قد تتكرر ❌ عناصر فريدة
الوصول فهرس [0] فهرس [0] مفتاح ["key"] لا يدعم الفهرسة
سرعة البحث O(n) بطيء O(n) بطيء O(1) سريع جداً O(1) سريع جداً
الاستخدام النموذجي بيانات مرتبة، مجموعات ديناميكية بيانات ثابتة، إرجاعات دوال تعيينات، تخزين مؤقت إزالة تكرار، عمليات مجموعات
💡 مبادئ الاختيار الرئيسية: 1) بحاجة وصول بالموقع → قائمة/صف؛ 2) بحاجة وصول بالاسم → قاموس؛ 3) بحاجة إزالة تكرار أو عمليات رياضية → مجموعة؛ 4) البيانات لا ينبغي أن تتغير → صف.

مثال: مقارنة اختيار الحاوية (الصعوبة ⭐⭐)

PYTHON
# نفس السيناريو منفذ بحاويات مختلفة

# السيناريو: تخزين أسماء الطلاب
# قائمة — مرتبة، سهلة الإضافة/الإزالة
students_list = ["Alice", "Bob", "Charlie"]
students_list.append("Diana")
print(f"List: {students_list[0]}")    # Alice

# صف — ثابت (مثل قائمة الفصل)
students_tuple = ("Alice", "Bob", "Charlie")
# students_tuple[0] = "xxx"     # خطأ! الصفوف غير قابلة للتعديل
print(f"Tuple: {students_tuple[0]}")   # Alice

# قاموس — بحث سريع بالمعرف
students_dict = {
    "001": "Alice",
    "002": "Bob",
    "003": "Charlie",
}
print(f"Dict: {students_dict['002']}")  # Bob — سرعة O(1)

# مجموعة — إزالة التكرارات (مثل قائمة الحضور)
attendance = {"Alice", "Bob", "Charlie", "Alice"}
print(f"Set: {attendance}")            # {'Bob', 'Charlie', 'Alice'} — أزيل تكرار Alice
▶ جرّب الكود

2. شاملات القوائم المتقدمة

الدرس 11 غطى الشاملات الأساسية. دعنا نتعمق أكثر.

شروط متعددة

PYTHON
numbers = range(1, 31)

# يقبل القسمة على 3 AND على 5
filtered = [n for n in numbers if n % 3 == 0 and n % 5 == 0]
print(filtered)             # [15, 30]

# يقبل القسمة على 3 OR على 5
filtered = [n for n in numbers if n % 3 == 0 or n % 5 == 0]
print(filtered)             # [3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24, 25, 27, 30]

شاملات الحلقات المتداخلة

PYTHON
# أنشئ أزواج إحداثيات — تعادل حلقة for مزدوجة
pairs = [(x, y) for x in range(3) for y in range(3)]
print(pairs)
# [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

# متداخلة مع شرط — ابحث عن الأزواج حيث المجموع زوجي
pairs = [(x, y) for x in range(3) for y in range(3) if (x + y) % 2 == 0]
print(pairs)
# [(0, 0), (0, 2), (1, 1), (2, 0), (2, 2)]

if-else في الشاملات

PYTHON
# if-else في الشاملات — لاحظ الموضع المختلف
numbers = [1, 2, 3, 4, 5, 6]

# فقط if (تصفية) — يوضع بعد
evens = [n for n in numbers if n % 2 == 0]

# if-else (تحويل) — يوضع قبل
result = ["even" if n % 2 == 0 else "odd" for n in numbers]
print(result)   # ['odd', 'even', 'odd', 'even', 'odd', 'even']

مثال: خط أنابيب تحويل البيانات (الصعوبة ⭐⭐⭐)

PYTHON
# سطر واحد: تصفية → تحويل → تنسيق
raw = ["  apple  ", "BANANA", "", "  CHERRY", None, "  date  "]

# صفّي None والسلاسل الفارغة → أزل المسافات → كبّر أول حرف
cleaned = [item.strip().capitalize() for item in raw if item and item.strip()]
print(cleaned)              # ['Apple', 'Banana', 'Cherry', 'Date']
▶ جرّب الكود

المخرجات:

TEXT
['Apple', 'Banana', 'Cherry', 'Date']

3. شاملات القاموس

يمكن للقواميس أيضاً استخدام الشاملات. الصيغة مشابهة للقوائم، لكنها تستخدم {} وتحدد أزواج المفتاح-القيمة:

PYTHON
# شاملات القاموس الأساسية
squares = {x: x ** 2 for x in range(5)}
print(squares)              # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# مع شرط
even_squares = {x: x ** 2 for x in range(10) if x % 2 == 0}
print(even_squares)         # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

# عكس المفاتيح والقيم
original = {"a": 1, "b": 2, "c": 3}
reversed_dict = {value: key for key, value in original.items()}
print(reversed_dict)        # {1: 'a', 2: 'b', 3: 'c'}

عملي: دمج قائمتين في قاموس

PYTHON
# ادمج قائمتين في قاموس
names = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]
result = {names[i]: scores[i] for i in range(len(names))}
print(result)               # {'Alice': 85, 'Bob': 92, 'Charlie': 78}

# استخدام zip() أكثر أناقة
result = {name: score for name, score in zip(names, scores)}
print(result)               # {'Alice': 85, 'Bob': 92, 'Charlie': 78}

4. شاملات المجموعات

شاملات المجموعات تستخدم {} مع تعبير فقط (بدون نقطتين) — الفرق عن شاملات القاموس هو وجود أو عدم وجود نقطتين:

PYTHON
# شاملة مجموعة — إزالة التكرارات تلقائياً
numbers = [1, 2, 2, 3, 3, 3, 4, 5, 5]
unique_squares = {x ** 2 for x in numbers}
print(unique_squares)       # {1, 4, 9, 16, 25}

# مع شرط
even_set = {x for x in range(20) if x % 2 == 0}
print(even_set)             # {0, 2, 4, 6, 8, 10, 12, 14, 16, 18}
💡 الفروقات الثلاثة: [x for x in ...] هي قائمة — مرتبة، التكرارات مسموحة. {x: y for x in ...} هو قاموس — به نقطتان. {x for x in ...} هي مجموعة — بدون نقطتين، غير مرتبة، بدون تكرارات.


حالات الاستخدام الشائعة


❓ أسئلة شائعة

س ما الفرق بين شاملات القوائم وتعبيرات المولدات؟
ج شاملات القوائم [x for x in range(10)] تُنشئ جميع البيانات مرة واحدة في الذاكرة. تعبيرات المولدات (x for x in range(10)) كسولة — قيمة واحدة في كل مرة، توفر الذاكرة. استخدم المولدات لمجموعات البيانات الكبيرة (عشرات الآلاف+). ⚠️ س:ماذا لو كانت الشاملة تحتوي على أكثر من مستويين من التداخل؟ ج:الشاملات التي تحتوي على أكثر من مستويين تصبح غير قابلة للقراءة. كود مثل [x for xs in matrix for ys in xs for x in ys] يكاد يكون مستحيل الفهم للوهلة الأولى. إذا كنت بحاجة لثلاثة+ مستويات، استخدم حلقات for العادية أو دوال مساعدة. س:كيف أقرر أي حاوية يجب استخدامها؟ ج:ثلاثة أسئلة: ① هل تحتاج مفاتيح فريدة؟ → قاموس. ② هل تحتاج إزالة تكرار أو عمليات مجموعات؟ → مجموعة. ③ هل تحتاج البيانات إلى التغيير؟ → قائمة إذا نعم، صف إذا لا. في معظم السيناريوهات، القوائم والقواميس تغطي 90% من حالات الاستخدام.

📖 ملخص

  • القوائم مرتبة وقابلة للتعديل؛ الصفوف مرتبة وغير قابلة للتعديل؛ القواميس هي مفتاح-قيمة مع بحث سريع؛ المجموعات لإزالة التكرار والعمليات الرياضية
  • شاملة قائمة: [expression for variable in iterable if condition]
  • شاملة قاموس: {key: value for variable in iterable if condition}
  • شاملة مجموعة: {expression for variable in iterable if condition}
  • if بعد الحلقة للتصفية؛ if-else قبل الحلقة للتحويل
  • الشاملات المتداخلة يمكنها توليد بيانات ثنائية الأبعاد، لكن أكثر من مستويين يتطلب حلقات عادية

📝 تمارين

  1. أساسي (الصعوبة ⭐): استخدم شاملة قائمة لتوليد جميع الأرقام بين 10 و 50 التي تقبل القسمة على 7 أو تحتوي على الرقم 7. تلميح: استخدم or لدمج شرطين.

  2. متوسط (الصعوبة ⭐⭐): بالنظر إلى قائمتين keys = ["name", "age", "city"] و values = ["Alice", 25, "Beijing"]، استخدم شاملة قاموس لدمجهما في قاموس. تلميح: استخدم zip(keys, values) لربطهما.

  3. تحدي (الصعوبة ⭐⭐⭐): اكتب "محلل بيانات." بالنظر إلى سلسلة تحتوي على عدة جمل، احسب وأخرج: إجمالي عدد الكلمات، عدد الكلمات الفريدة، والكلمات الثلاث الأكثر تكراراً. تلميح: استخدم split() للتقسيم، قاموساً للعد، و sorted(dict.items(), key=lambda x: x[1], reverse=True)[:3] لأول 3.

100%