القواميس والمجموعات
في الدرسين السابقين غطينا القوائم والصفوف، التي يتم الوصول إليها "بالموضع." لكن في الحياة الواقعية، غالباً ما نبحث عن الأشياء "بالاسم" — القواميس بالكلمة، جهات الاتصال بالاسم. القواميس (dict) تتعامل مع هذا. المجموعات مخصصة للعمليات الرياضية على المجموعات. كلاهما مفيد جداً في معالجة البيانات.
1. ما هو القاموس
يُعرّف القاموس بأقواس متعرجة {}، يحتوي على مجموعة من أزواج المفتاح-القيمة، مفصولة بنقطتين.
# تعريف قاموس
student = {
"name": "Alice",
"age": 20,
"city": "Beijing"
}
print(student) # {'name': 'Alice', 'age': 20, 'city': 'Beijing'}
print(type(student)) # <class 'dict'>
عمليات CRUD الأساسية
# أنشئ قاموساً
user = {}
# أضف / عدّل أزواج المفتاح-القيمة
user["name"] = "Alice"
user["age"] = 25
print(user) # {'name': 'Alice', 'age': 25}
# عدّل مفتاحاً موجوداً
user["age"] = 26
print(user) # {'name': 'Alice', 'age': 26}
# اقرأ قيمة
print(user["name"]) # Alice
# print(user["email"]) # KeyError! مفتاح غير موجود يُثير خطأ
# استخدم get() للوصول الآمن — يُرجع القيمة الافتراضية إذا المفتاح غير موجود
print(user.get("email")) # None — غير موجود، يُرجع None
print(user.get("email", "not set")) # not set — قيمة افتراضية مخصصة
# احذف زوج مفتاح-قيمة
del user["age"]
print(user) # {'name': 'Alice'}
dict["non_existent_key"] يُثير KeyError. استخدم get() لتجنب هذا — يُرجع None أو القيمة الافتراضية التي تحددها.
مثال: إدارة معلومات الطالب (الصعوبة ⭐)
# خزّن معلومات الطالب الكاملة في قاموس
student = {
"name": "Bob",
"id": "2024001",
"scores": {"Chinese": 85, "Math": 92, "English": 78},
"is_active": True
}
# اقرأ المعلومات الأساسية
print(f"Name: {student['name']}")
print(f"ID: {student['id']}")
# اقرأ من قاموس متداخل
math_score = student["scores"]["Math"]
print(f"Math score: {math_score}")
# وصول آمن باستخدام get
phone = student.get("phone", "not filled")
print(f"Phone: {phone}")
المخرجات:
Name: Bob
ID: 2024001
Math score: 92
Phone: not filled
2. طرق القاموس الشائعة
الحصول على جميع المفاتيح، القيم، وأزواج المفتاح-القيمة
user = {"name": "Alice", "age": 25, "city": "Beijing"}
print(user.keys()) # dict_keys(['name', 'age', 'city'])
print(user.values()) # dict_values(['Alice', 25, 'Beijing'])
print(user.items()) # dict_items([('name', 'Alice'), ('age', 25), ('city', 'Beijing')])
# الطريقة الأكثر شيوعاً للتكرار على قاموس
for key, value in user.items():
print(f"{key} = {value}")
المخرجات:
name = Alice
age = 25
city = Beijing
pop() و setdefault()
# pop() — أزل وأرجع القيمة لمفتاح
user = {"name": "Alice", "age": 25, "city": "Beijing"}
city = user.pop("city")
print(f"Removed city: {city}") # Removed city: Beijing
print(user) # {'name': 'Alice', 'age': 25}
# pop() يمكنه تحديد قيمة افتراضية، متجنباً KeyError
email = user.pop("email", "no email")
print(email) # no email — المفتاح غير موجود، يُرجع الافتراضي
# setdefault() — إذا كان المفتاح موجوداً، أرجع قيمته؛ إذا لم يكن، أدخل الافتراضي
user = {"name": "Alice"}
result = user.setdefault("age", 18)
print(user) # {'name': 'Alice', 'age': 18}
# إذا كان المفتاح موجوداً بالفعل، setdefault لا يعدله
result = user.setdefault("name", "Bob")
print(user) # {'name': 'Alice', 'age': 18} — لم يتغير
update() — دمج القواميس
# ادمج قاموسين
defaults = {"theme": "light", "lang": "en", "font_size": 14}
custom = {"theme": "dark", "font_size": 16}
defaults.update(custom) # custom يكتب فوق المفاتيح المتطابقة في defaults
print(defaults) # {'theme': 'dark', 'lang': 'en', 'font_size': 16}
مثال: عد الكلمات (الصعوبة ⭐⭐)
# عد ظهور الكلمات في جملة
text = "apple banana apple orange banana apple"
word_count = {}
for word in text.split():
# إذا كانت الكلمة موجودة بالفعل في القاموس، زد؛ وإلا، اجعلها 1
word_count[word] = word_count.get(word, 0) + 1
print(word_count) # {'apple': 3, 'banana': 2, 'orange': 1}
# الإخراج باستخدام items()
for word, count in word_count.items():
print(f"{word}: {count} times")
المخرجات:
apple: 3 times
banana: 2 times
orange: 1 times
3. التكرار على القاموس والتداخل
ثلاث طرق للتكرار على قاموس
user = {"name": "Alice", "age": 25, "city": "Beijing"}
# الطريقة 1: التكرار على المفاتيح
for key in user: # تعادل for key in user.keys():
print(f"{key}: {user[key]}")
# الطريقة 2: التكرار على القيم
for value in user.values():
print(value)
# الطريقة 3: التكرار على أزواج المفتاح-القيمة (موصى به)
for key, value in user.items():
print(f"{key} → {value}")
القواميس المتداخلة
# قاموس متداخل — تخزين سجلات طلاب متعددة
students = {
"1001": {"name": "Alice", "scores": [85, 90, 78]},
"1002": {"name": "Bob", "scores": [92, 88, 95]},
"1003": {"name": "Charlie", "scores": [76, 85, 82]},
}
# التكرار على قاموس متداخل
for sid, info in students.items():
name = info["name"]
avg = sum(info["scores"]) / len(info["scores"])
print(f"{sid} {name}: Average {avg:.1f}")
المخرجات:
1001 Alice: Average 84.3
1002 Bob: Average 91.7
1003 Charlie: Average 81.0
4. ما هي المجموعة
تُعرّف المجموعة بأقواس متعرجة {} أو set(). تبدو كقاموس لكن لا توجد قيم، فقط مفاتيح. المجموعات: عناصر فريدة، غير مرتبة.
# تعريف مجموعة
fruits = {"apple", "banana", "orange", "apple"} # التكرارات تُزال تلقائياً
print(fruits) # {'orange', 'apple', 'banana'} — الترتيب قد يختلف
# أنشئ مجموعة من قائمة
numbers = set([1, 2, 2, 3, 3, 3])
print(numbers) # {1, 2, 3} — التكرارات أزيلت
# المجموعة الفارغة يجب أن تستخدم set()، وليس {} ({} هي قاموس فارغ)
empty_set = set()
print(type(empty_set)) # <class 'set'>
list(set(list_name)) يزيل التكرارات بسرعة. لكن لاحظ أن المجموعات غير مرتبة، لذا الترتيب الأصلي يُفقد.
عمليات المجموعة الأساسية
# إضافة وإزالة
s = set()
s.add("apple")
s.add("banana")
s.add("apple") # إضافة مكررة ليس لها تأثير
print(s) # {'apple', 'banana'}
s.discard("apple") # إزالة؛ لا خطأ إذا لم يُعثر عليه
print(s) # {'banana'}
# s.remove("non_existent") # سيُثير KeyError!
5. عمليات المجموعات
هذا هو المجال الذي تتألق فيه المجموعات حقاً — التقاطع والاتحاد والفرق الرياضية:
a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}
# التقاطع — عناصر موجودة في كلتا المجموعتين
print(a & b) # {4, 5}
print(a.intersection(b)) # نفس الشيء
# الاتحاد — جميع العناصر من كلا المجموعتين (بدون تكرار)
print(a | b) # {1, 2, 3, 4, 5, 6, 7, 8}
print(a.union(b)) # نفس الشيء
# الفرق — عناصر في a وليست في b
print(a - b) # {1, 2, 3}
print(a.difference(b)) # نفس الشيء
# الفرق المتماثل — عناصر في a أو b ولكن ليس كلاهما
print(a ^ b) # {1, 2, 3, 6, 7, 8}
مثال: تحليل أذونات المستخدم (الصعوبة ⭐⭐⭐)
# محاكاة علاقات مستخدمي منصة اجتماعية
all_users = {"Alice", "Bob", "Charlie", "Diana", "Eve"}
vip_users = {"Bob", "Diana", "Eve"}
blocked_users = {"Diana"}
# ابحث عن "المستخدمين العاديين الذين ليسوا VIP"
normal_users = all_users - vip_users - blocked_users
print(f"Normal users: {normal_users}")
# ابحث عن "VIP النشطين (غير المحظورين)"
active_vip = vip_users - blocked_users
print(f"Active VIPs: {active_vip}")
# ابحث عن "المستخدمين المحظورين الذين هم VIP"
blocked_vip = vip_users & blocked_users
print(f"Blocked VIPs: {blocked_vip}")
# ابحث عن "جميع المستخدمين الذين يحتاجون إشعاراً (VIP + محظورين)"
notify_users = vip_users | blocked_users
print(f"Users to notify: {notify_users}")
المخرجات:
Normal users: {'Alice', 'Charlie'}
Active VIPs: {'Bob', 'Eve'}
Blocked VIPs: {'Diana'}
Users to notify: {'Bob', 'Diana', 'Eve'}
حالات الاستخدام الشائعة
- إدارة التهيئة: خزّن معاملات التهيئة (مفتاح = اسم الإعداد، قيمة = قيمة الإعداد)؛ استخدم
get()مع القيم الافتراضية. - عد التكرارات: استخدم القاموس كعداد —
dict[key] = dict.get(key, 0) + 1لكل ظهور. - تجميع البيانات: قواميس متداخلة
{"department": [employee_list]}للتجميع حسب القسم. - إزالة التكرارات: المجموعة تزيل التكرارات تلقائياً؛
list(set(data))لإزالة سريعة (بدون ترتيب)؛dict.fromkeys(data)للإزالة مع الحفاظ على الترتيب. - فحوصات الأذونات: عمليات المجموعة للتقاطع (الأذونات المتداخلة) والفرق (الأذونات المفقودة).
❓ أسئلة شائعة
discard() و remove()؟ ج:remove() يُثير KeyError إذا العنصر غير موجود. discard() لا يفعل — يزيل إذا كان موجوداً، أو لا يفعل شيئاً بصمت إذا لم يكن. إذا كنت غير متأكد من وجود عنصر، استخدم discard() للأمان.📖 ملخص
- القواميس تستخدم
{}، تخزّن أزواج المفتاح-القيمة، وتبحث عن القيم بالمفتاح بسرعة - العمليات الأساسية:
dict[key]قراءة/كتابة،get()قراءة آمنة،delحذف - الطرق الشائعة:
keys()،values()،items()للتكرار؛pop()إزالة وإرجاع؛update()دمج setdefault()يُرجع القيمة الموجودة أو يُدخل قيمة افتراضية- قيم القاموس يمكن أن تكون أي نوع، بما في ذلك القوائم والقواميس — مما يتيح هياكل متداخلة
- المجموعات تستخدم
{}أوset()، فريدة وغير مرتبة، أساساً لإزالة التكرارات والعمليات الرياضية - عمليات المجموعات:
&تقاطع،|اتحاد،-فرق،^فرق متماثل
📝 تمارين
-
أساسي (الصعوبة ⭐): أنشئ قاموساً لمعلوماتك الشخصية (الاسم، العمر، المدينة، الهواية). استخدم
get()لقراءة حقل "الوظيفة" (أرجع "غير محدد" إذا كان مفقوداً). استخدمitems()لإخراج جميع أزواج المفتاح-القيمة. -
متوسط (الصعوبة ⭐⭐): بالنظر إلى الجملة
"hello world hello python world hello"، احسب عدد مرات ظهور كل كلمة وابحث عن الكلمة الأكثر تكراراً. تلميح: استخدم قاموساً للعد؛ استخدمmax(dict.items(), key=lambda x: x[1])للعثور على القيمة القصوى. -
تحدي (الصعوبة ⭐⭐⭐): اكتب برنامج "دفتر عناوين بسيط." استخدم قاموساً (الاسم ← رقم الهاتف). ادعم:
add Alice 13800138000،del Alice،find Alice،all(عرض الكل). استخدمwhile True؛exitللخروج. تلميح: استخدمsplit()لتحليل الأوامر.



