القواميس في بايثون: احفظ كل قيمة باسمها لا برقمها

تعلّم إنشاء القواميس في بايثون، وقراءة القيم بالمفتاح، وإضافتها وتعديلها وحذفها، والمرور عليها بـ items، وتجنّب خطأ KeyError.

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

🎯 ماذا ستتعلم؟

بنهاية هذا الدرس ستكون قادرًا على:

  • إنشاء قاموس فارغ أو قاموس فيه بيانات جاهزة.
  • قراءة قيمة باستخدام مفتاحها بدل رقم مكانها.
  • إضافة عناصر جديدة وتعديل القيم الموجودة.
  • المرور على كل المفاتيح والقيم بحلقة for.
  • حذف عنصر من القاموس وتجنّب خطأ KeyError.

🧰 ماذا تحتاج قبل أن تبدأ؟

يجب أن تعرف المتغيّرات والقوائم، وأن تكون جرّبت حلقة for والشروط ولو قليلًا. كل الأمثلة تعمل في مترجم بايثون في المتصفح بدون تثبيت.

الفكرة ببساطة

فكّر في دفتر الهواتف الموجود في جوّالك. أنت لا تبحث عن رقم صديقك بموقعه في الدفتر، بل تكتب اسمه فيظهر رقمه. الاسم هو الذي يوصلك إلى الرقم.

هذا بالضبط هو القاموس (dictionary) في بايثون. هو متغيّر واحد يحفظ أزواجًا من المعلومات. كل زوج فيه مفتاح (key) مثل الاسم، وقيمة (value) مثل رقم الهاتف.

الفرق بينه وبين القائمة بسيط. القائمة تصل إلى عناصرها بالفهرس، أي بالرقم 0 و1 و2. أما القاموس فتصل إلى عناصره بالمفتاح، وهو غالبًا كلمة لها معنى.

الخطوة 1: إنشاء قاموس

يُكتب القاموس بين قوسين معقوصين { }. داخلهما تكتب المفتاح، ثم نقطتين :، ثم القيمة. وتفصل بين كل زوج والذي بعده بفاصلة. هنا قاموس بدرجات ثلاثة طلاب:

grades = {"سالم": 90, "نورة": 85, "خالد": 78}
print(grades)
{'سالم': 90, 'نورة': 85, 'خالد': 78}

لاحظ أن بايثون تطبع القاموس كاملًا بأقواسه. ويمكنك أيضًا إنشاء قاموس فارغ لتملأه لاحقًا:

phonebook = {}
print(phonebook)
{}

الخطوة 2: القراءة بالمفتاح

لقراءة قيمة، اكتب اسم القاموس ثم المفتاح بين قوسين مربّعين. تمامًا كما تفعل مع القائمة، لكن بدل الرقم تكتب المفتاح:

grades = {"سالم": 90, "نورة": 85, "خالد": 78}
print(grades["نورة"])
print(grades["سالم"])
85
90

لا يهم كم عدد الطلاب في القاموس. تكتب الاسم، فتحصل على الدرجة مباشرة. ويمكنك تخزين القيمة في متغيّر واستخدامها كما تشاء:

grades = {"سالم": 90, "نورة": 85, "خالد": 78}
best = grades["سالم"]
print("أعلى درجة هي", best)
أعلى درجة هي 90

الخطوة 3: الإضافة والتعديل

لإضافة زوج جديد، اكتب اسم القاموس والمفتاح الجديد بين قوسين مربّعين، ثم ضع القيمة بعلامة =. هنا نبني دفتر هواتف من الصفر:

phonebook = {}
phonebook["أمي"] = "0501234567"
phonebook["أبي"] = "0559876543"
print(phonebook)
{'أمي': '0501234567', 'أبي': '0559876543'}

وإذا كتبت مفتاحًا موجودًا من قبل، فلن يُضاف زوج ثانٍ. بايثون تستبدل القيمة القديمة بالجديدة. هنا أعاد خالد الاختبار وحسّن درجته:

grades = {"سالم": 90, "نورة": 85, "خالد": 78}
grades["خالد"] = 88
print(grades)
{'سالم': 90, 'نورة': 85, 'خالد': 88}

القاعدة المهمة: كل مفتاح في القاموس يظهر مرة واحدة فقط. لا يمكن أن يكون عندك مفتاحان بالاسم نفسه.

🚀 للمتقدمين: المفاتيح لا تكون نصوصًا فقط. يمكن أن تكون أرقامًا، مثل {1: "الأول", 2: "الثاني"}. لكن القائمة لا تصلح مفتاحًا، لأنها قابلة للتغيير. والقيمة يمكن أن تكون أي شيء، حتى قائمة أو قاموسًا آخر.

الخطوة 4: المرور على القاموس

ماذا لو أردت طباعة كل طالب مع درجته؟ الطريقة items() تعطيك الأزواج واحدًا واحدًا. في كل دورة من الحلقة، يذهب المفتاح إلى متغيّر والقيمة إلى متغيّر آخر:

grades = {"سالم": 90, "نورة": 85, "خالد": 78}
for name, grade in grades.items():
    print(name, "حصل على", grade)
سالم حصل على 90
نورة حصل على 85
خالد حصل على 78

اقرأ السطر الثاني هكذا: “لكل اسم ودرجة في أزواج القاموس، افعل ما يلي”. لاحظ أن بايثون تعرض الأزواج بالترتيب نفسه الذي أضفتها به.

وإذا احتجت المفاتيح وحدها، مرّ على القاموس مباشرة بدون items():

grades = {"سالم": 90, "نورة": 85, "خالد": 78}
for name in grades:
    print(name)
سالم
نورة
خالد

وكما مع القوائم، تعطيك len() عدد الأزواج في القاموس:

grades = {"سالم": 90, "نورة": 85, "خالد": 78}
print(len(grades))
3

الخطوة 5: الحذف من القاموس

لحذف زوج، استخدم الكلمة del ثم اسم القاموس والمفتاح. هنا انتقل خالد إلى مدرسة أخرى:

grades = {"سالم": 90, "نورة": 85, "خالد": 78}
del grades["خالد"]
print(grades)
{'سالم': 90, 'نورة': 85}

وهناك طريقة ثانية اسمها pop(). هي تحذف الزوج أيضًا، لكنها تعيد لك القيمة المحذوفة لتستخدمها قبل أن تضيع:

grades = {"سالم": 90, "نورة": 85, "خالد": 78}
removed = grades.pop("خالد")
print("حذفنا الدرجة", removed)
print(grades)
حذفنا الدرجة 78
{'سالم': 90, 'نورة': 85}

الخطوة 6: الخطأ الشهير KeyError

ماذا يحدث لو طلبت مفتاحًا غير موجود؟ لا يوجد طالب اسمه “ليلى” في القاموس التالي، فيتوقف البرنامج بخطأ:

❌ هذا الكود يتوقف بخطأ
grades = {"سالم": 90, "نورة": 85}
print(grades["ليلى"])

KeyError: 'ليلى'

الرسالة تعني: “المفتاح غير موجود”. الحل أن تتحقق أولًا بالكلمة in، فهي تعطيك True إذا كان المفتاح موجودًا:

# ✅ نتحقق قبل أن نقرأ
grades = {"سالم": 90, "نورة": 85}
if "ليلى" in grades:
    print(grades["ليلى"])
else:
    print("ليلى ليست في القائمة")
ليلى ليست في القائمة

🚀 للمتقدمين: الطريقة get() تختصر عليك الشرط. grades.get("ليلى", 0) تعيد الدرجة إن وُجدت، وإلا تعيد القيمة الاحتياطية 0 بدون أي خطأ. جرّب print(grades.get("ليلى", "غير موجود")).

⚠️ أخطاء شائعة

الأخطاء جزء طبيعي من التعلّم، وكل مبرمج وقع فيها. إليك ثلاثة تقابلها كثيرًا مع القواميس:

1. استخدام الفهرس بدل المفتاح

❌
grades = {"سالم": 90, "نورة": 85}
print(grades[0])
KeyError: 0

القاموس لا يعرف “العنصر الأول”. هو يبحث عن مفتاح اسمه 0 فلا يجده. استخدم المفتاح الحقيقي:

# ✅
grades = {"سالم": 90, "نورة": 85}
print(grades["سالم"])
90

2. نسيان علامات الاقتباس حول المفتاح

❌
grades = {"سالم": 90, "نورة": 85}
print(grades[سالم])
NameError: name 'سالم' is not defined

بدون علامات الاقتباس، تظن بايثون أن سالم متغيّر، فتبحث عنه ولا تجده. المفتاح النصي يحتاج دائمًا إلى علامات اقتباس:

# ✅
grades = {"سالم": 90, "نورة": 85}
print(grades["سالم"])
90

3. الظن أن المفتاح المكرّر يضيف عنصرًا جديدًا

❌
scores = {"سالم": 10}
scores["سالم"] = 25
print(len(scores))
1

الكود لا يتوقف، لكن القاموس ما زال فيه عنصر واحد. الإضافة بمفتاح موجود تعدّل القيمة ولا تكرّر المفتاح. إذا أردت أن تجمع النقاط، اجمعها على القيمة القديمة:

# ✅
scores = {"سالم": 10}
scores["سالم"] = scores["سالم"] + 25
print(scores)
{'سالم': 35}

🧪 جرّب بنفسك

التحدي 1: حقيبة اللعبة

أنشئ قاموسًا فارغًا اسمه bag، وأضف إليه ثلاثة أغراض من لعبتك المفضّلة مع عدد كل غرض، ثم اطبع القاموس وعدد أزواجه.

# أنشئ القاموس وأضف ثلاثة أغراض
bag = {}
print(bag)
{}
💡 اضغط لرؤية الحل
bag = {}
bag["جرعة"] = 3
bag["سهم"] = 20
bag["مفتاح"] = 1
print(bag)
print(len(bag))
{'جرعة': 3, 'سهم': 20, 'مفتاح': 1}
3

التحدي 2: أهداف الفريق

عندك قاموس بأهداف لاعبي فريقك هذا الموسم. سجّل “فهد” هدفين جديدين، ثم اطبع كل لاعب مع أهدافه في سطر مستقل.

goals = {"عمر": 5, "فهد": 3, "يوسف": 7}
# زد أهداف فهد بـ 2 ثم اطبع الجميع
print(goals)
{'عمر': 5, 'فهد': 3, 'يوسف': 7}
💡 اضغط لرؤية الحل
goals = {"عمر": 5, "فهد": 3, "يوسف": 7}
goals["فهد"] = goals["فهد"] + 2
for player, count in goals.items():
    print(player, "سجّل", count, "أهداف")
عمر سجّل 5 أهداف
فهد سجّل 5 أهداف
يوسف سجّل 7 أهداف

التحدي 3: جدول الحصص

عندك قاموس يربط كل يوم بأول حصة فيه. اقرأ الأيام في القائمة days، واطبع حصة كل يوم إن كان موجودًا في القاموس. وإن لم يكن موجودًا، اطبع أنه يوم إجازة.

timetable = {"الأحد": "رياضيات", "الاثنين": "علوم", "الثلاثاء": "لغة عربية"}
days = ["الأحد", "الجمعة", "الثلاثاء"]
# اطبع الحصة أو كلمة إجازة لكل يوم
print(len(days))
3
💡 اضغط لرؤية الحل
timetable = {"الأحد": "رياضيات", "الاثنين": "علوم", "الثلاثاء": "لغة عربية"}
days = ["الأحد", "الجمعة", "الثلاثاء"]
for day in days:
    if day in timetable:
        print(day, ":", timetable[day])
    else:
        print(day, ": إجازة")
الأحد : رياضيات
الجمعة : إجازة
الثلاثاء : لغة عربية

✅ اختبر نفسك

  1. ماذا يطبع print({"أ": 1, "ب": 2}["ب"])؟

    • أ) 1
    • ب) 2
    • ج) ب
  2. عندك قاموس فيه مفتاح “سالم”. ماذا يحدث عند تنفيذ grades["سالم"] = 100؟

    • أ) يُضاف مفتاح ثانٍ اسمه “سالم”
    • ب) تتغيّر قيمة “سالم” إلى 100
    • ج) يتوقف البرنامج بخطأ
  3. صح أم خطأ: طلب مفتاح غير موجود يسبّب خطأ IndexError.

💡 اضغط لرؤية الإجابات
  1. ب) 2، لأن المفتاح “ب” مرتبط بالقيمة 2.
  2. ب) تتغيّر قيمة “سالم” إلى 100، فالمفتاح الموجود تُستبدل قيمته ولا يتكرّر.
  3. خطأ. الخطأ اسمه KeyError، أما IndexError فيخصّ القوائم.

📝 الخلاصة

  • القاموس يحفظ أزواجًا من مفتاح وقيمة، ويُكتب بين { }.
  • تصل إلى القيمة بمفتاحها، مثل grades["نورة"]، لا برقم مكانها.
  • الكتابة بمفتاح جديد تضيف زوجًا، والكتابة بمفتاح موجود تعدّل قيمته.
  • items() تعطيك المفاتيح والقيم معًا داخل حلقة for.
  • del وpop() تحذفان زوجًا، وin تحميك من خطأ KeyError.

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

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