تعلم البرمجة مع Python


الدرس: استخدم القواميس (Dictionaries)


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

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

إنشاء وطباعة القواميس



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

لكن دعونا لا نتوقع. اكتشفنا في الفصلين السابقين القوائم. الكائنات من هذا النوع هي كائنات حاوية ، نجد فيها كائنات أخرى. للوصول إلى هذه الكائنات المحتواة ، يجب أن تعرف موقعها في القائمة. ينتج عن هذا الموضع أعداد صحيحة ، تسمى مؤشرات ، بين 0 (مضمنة) وحجم القائمة (غير مدرج). كل هذا يجب أن تعرفه بالفعل.

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

إنشاء قاموس


مرة أخرى، وأنا أعطيك اسم الفئة التي فيها يمكننا انشاء القاموس:  dict . يجب أن تجد أيضًا الطريقة الأولى لإنشاء مثيل للقاموس:


>>> mon_dictionnaire = dict()
>>> type(mon_dictionnaire)
<class 'dict'>
>>> mon_dictionnaire
{}
>>> # لذلك يجب أن تجد الطريقة الثانية لإنشاء قاموس فارغ
... mon_dictionnaire = {}
>>> mon_dictionnaire
{}
>>>
 
الأقواس تحدد الصفوف ، والأقواس المربعة ، تحدد القوائم ، والأقواس المعقوفة {}تحدد القواميس.

دعونا نرى كيفية إضافة مفاتيح وقيم إلى قاموسنا الفارغ:


>>> mon_dictionnaire = {}
>>> mon_dictionnaire["pseudo"] = "Prolixe"
>>> mon_dictionnaire["mot de passe"] = "*"
>>> mon_dictionnaire
{'mot de passe': '*', 'pseudo': 'Prolixe'}
>>>
 
نشير بين قوسين معقوفين المفتاح الذي نريد الوصول إليه. في حالة عدم وجود المفتاح ، تتم إضافته إلى القاموس بالقيمة المحددة بعد العلامة = . خلافًا لذلك ، يتم استبدال القيمة القديمة في الموقع المحدد بالقيمة الجديدة:


>>> mon_dictionnaire = {}
>>> mon_dictionnaire["pseudo"] = "Prolixe"
>>> mon_dictionnaire["mot de passe"] = "*"
>>> mon_dictionnaire["pseudo"] = "6pri1"
>>> mon_dictionnaire
{'mot de passe': '*', 'pseudo': '6pri1'}
>>>
 
تم استبدال القيمة  'Prolixe' التي يشير إليها المفتاح  'pseudo'في السطر 4 بالقيمة '6pri1' . يجب أن يذكرك هذا بإنشاء المتغيرات: إذا كان المتغير غير موجود ، يتم إنشاؤه ، وإلا يتم استبداله بالقيمة الجديدة.

للوصول إلى قيمة مفتاح معين ، الأمر بسيط للغاية:


>>> mon_dictionnaire["mot de passe"]
'*'
>>>
 
إذا كان المفتاح غير موجود في القاموس ،  فسيتم طرح استثناء من النوع . KeyError

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

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


>>> mon_dictionnaire = {}
>>> mon_dictionnaire[0] = "a"
>>> mon_dictionnaire[1] = "e"
>>> mon_dictionnaire[2] = "i"
>>> mon_dictionnaire[3] = "o"
>>> mon_dictionnaire[4] = "u"
>>> mon_dictionnaire[5] = "y"
>>> mon_dictionnaire
{0: 'a', 1: 'e', 2: 'i', 3: 'o', 4: 'u', 5: 'y'}
>>>
 
لدينا انطباع بإعادة إنشاء طريقة عمل القائمة ، ولكن هذا ليس هو الحال: تذكر أن القاموس لا يحتوي على بنية مرتبة. على سبيل المثال ، إذا قمت بحذف الفهرس 2، فلن يقوم القاموس ، بخلاف القوائم ، بإزاحة جميع المفاتيح التي تحتوي على فهرس أكبر من الفهرس المحذوف.

يمكنك استخدام أي نوع تقريبًا كمفتاح ، ويمكنك استخدام أي نوع كقيمة.

فيما يلي مثال عن المفاتيح: نريد تمثيل رقعة الشطرنج. تقليديا ، يتم تمثيل مربع رقعة الشطرنج بحرف (من A إلى H ) متبوعًا برقم (من 1 إلى 8). يحدد الحرف العمود والرقم يحدد الصف. إذا لم تكن متأكدًا من فهمك ، فقم بإلقاء نظرة على الشكل التالي.

python
لماذا لا تنشئ قاموسًا تكون مفاتيحه عبارة عن مجموعات تحتوي على الحرف والرقم الذي يحدد المربع ، والذي نربط به اسم الأجزاء كقيم؟

echiquier = {}
echiquier['a', 1] = "tour blanche" # أسفل يسار رقعة الشطرنج
echiquier['b', 1] = "cavalier blanc" # على يمين القلعة
echiquier['c', 1] = "fou blanc" # على يمين الفارس
echiquier['d', 1] = "reine blanche" # على يمين الفيل
# ... السطر الأول الابيض
echiquier['a', 2] = "pion blanc" 
echiquier['b', 2] = "pion blanc" # أمام الفارس إلى يمين البيدق
# ... الخط الأبيض الثاني
 
في هذا المثال ، لدينا مجموعات ضمنية. لم يتم وضعها بين قوسين. تتفهم Python أننا نريد إنشاء مجموعات ، وهذا أمر جيد ، لكن الشيء المهم هو أنك تفهم ذلك أيضًا. تشجع بعض الدورات التدريبية وضع الأقواس دائمًا حول المجموعات عند استخدامها. من ناحيتي ، أعتقد ، إذا كنت تضع في اعتبارك أن هذه هي مجموعات ، وأنه ليس لديك مشكلة في تحديدها ، فهذا يكفي. إذا كنت محتارًا ، فضع أقواسًا حول الصفوف في جميع الظروف.

يمكنك أيضًا إنشاء قواميس مملوءة بالفعل:


placard = {"chemise":3, "pantalon":6, "tee-shirt":7}
 
يتم تحديد المفتاح والنقطتين ":" والقيمة المقابلة بين علامتي اقتباس. نفصل الأزواج المختلفين key : value بفاصلة. هذه أيضًا طريقة عرض Python للقاموس عندما تطلب ذلك.

ربما حاول بعض الأشخاص إنشاء قواميس تم ملؤها بالفعل قبل أن أوضح كيف. توضيح بسيط ، إذا كتبت تعليمة مشابهة لـ:


mon_dictionnaire = {'pseudo', 'mot de passe'}
 
مع مثل هذه التعليمات ، فإنه ليس قاموسًا تقوم بإنشائه ، ولكن ملف set .

 set (مجموعة) هو كائن حاوية (أيضًا) ، يشبه إلى حد بعيد القوائم باستثناء أنه لا يمكن أن يحتوي على كائنين متطابقين. لا يمكنك العثور مرتين في set على عدد صحيح 3على سبيل المثال. اسمح لك بالاستفسار عنها sets إذا كنت ترغب في ذلك.

إزالة المفاتيح من القاموس


بالنسبة للقوائم ، لديك احتمالان لكنهما يعودان إلى نفس الشيء:

  • الكلمة del .
  • طريقة القاموس pop .
لن أسهب في الحديث عن الكلمة الأساسية del، فهي تعمل بنفس طريقة عمل القوائم:

placard = {"chemise":3, "pantalon":6, "tee shirt":7}
del placard["chemise"]
 
تقوم الطريقة pop أيضًا بإزالة المفتاح المحدد ولكنها تُرجع القيمة المُزالة:

>>> placard = {"chemise":3, "pantalon":6, "tee shirt":7}
>>> placard.pop("chemise")
3
>>>
 
بالإضافة إلى إزالة المفتاح والقيمة المرتبطة ، pop تُرجع الطريقة هذه القيمة. يمكن أن يكون هذا مفيدًا في بعض الأحيان.

الكثير من أجل النظرة العامة. لقد كان موجزًا ​​ولم ترَ كل الأساليب بالطبع. اسمح لك باستشارة المساعدة للحصول على قائمة مفصلة.

ابعد بقليل


تستخدم القواميس أحيانًا لتخزين الوظائف.

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

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


>>> print_2 = print # print  إلى وظيفة print_2 سيشير كائن 
>>> print_2("Affichons un message")
Affichons un message
>>>
 
نقوم بنسخ الدالة print إلى متغير آخر print_2 . يمكننا بعد ذلك استدعاء print_2 وستعرض الوظيفة النص المُدخل ، تمامًا كما  كانت ستفعل print .

في الممارسة العملية ، نادراً ما يتم تعيين الوظائف بهذه الطريقة. انها قليلة الاستخدام. من ناحية أخرى ، نضع أحيانًا وظائف في القواميس:


>>> def fete():
...     print("C'est la fête.")
... 
>>> def oiseau():
...     print("Fais comme l'oiseau...")
...
>>> fonctions = {}
>>> fonctions["fete"] = fete # لا نضع الاقواس
>>> fonctions["oiseau"] = oiseau
>>> fonctions["oiseau"]
<function oiseau at 0x00BA5198>
>>> fonctions["oiseau"]() # نحاول استدعائها
Fais comme l'oiseau...
>>>
 
لنأخذ بالترتيب إذا كنت لا تمانع:
  • نبدأ بتحديد وظيفتين ، fete و oiseau (اغفر لي المثال ) .
  • نقوم بإنشاء قاموس مسمى fonctions .
  • نضع في هذا القاموس وظائف fete و oiseau . المفتاح الذي يشير إلى الوظيفة هو اسم الوظيفة ، بكل بساطة ، لكن كان بإمكاننا إعطائها اسمًا أصليًا أكثر.
  • نحاول الوصول إلى الوظيفة oiseau عن طريق الكتابة fonctions["oiseau"] . تعطينا بايثون شيئًا قبيحًا جدًا ،  لكنك حصلت على الفكرة: إنها وظيفتنا بالفعل oiseau . ومع ذلك ، لتسميتها ، تحتاج إلى أقواس ، كما هو الحال بالنسبة لأي دالة تحترم نفسها.
  • عن طريق الكتابة fonctions["oiseau"]()، يمكنك الوصول إلى الوظيفة oiseau واستدعائها على الفور.
يمكننا تخزين مراجع الوظائف في أي كائن حاوية ، قوائم ، قواميس ... وفئات أخرى ، عندما نتعلم كيفية القيام بذلك. أنا لا أطلب منك أن تفهم تمامًا التعامل مع المراجع الوظيفية ، فقط حاول أن تتذكر هذا المثال. على أي حال ، ستتاح لنا الفرصة للعودة إليه.

طُرق التصفح



كما يمكنك أن تتخيل ، فإن تصفح القاموس لا يشبه تمامًا تصفح القائمة. الفرق ليس بهذا الضخامة ، ولكن في معظم الأحيان نستخدم طرق القاموس.

التصفح الرئيسي

ربما حاولت بالفعل تصفح القاموس بنفسك كما فعلنا مع القوائم:


>>> fruits = {"pommes":21, "melons":3, "poires":31}
>>> for cle in fruits:
...     print(cle)
... 
melons
poires
pommes
>>>
 
كما ترى ، إذا حاولنا تصفح القاموس "ببساطة" ، فإننا في الواقع نتصفح قائمة المفاتيح الموجودة في القاموس.

لكن ... المفاتيح لا تظهر بالترتيب الذي تم إدخالها به ... هل هذا طبيعي؟

ليس للقواميس بنية منظمة ، ضع ذلك في الاعتبار. بهذا المعنى ، نعم ، إنه أمر طبيعي تمامًا.

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


>>> fruits = {"pommes":21, "melons":3, "poires":31}
>>> for cle in fruits.keys():
...     print(cle)
... 
melons
poires
pommes
>>>
 
الطريقة keys ("المفاتيح" باللغة الإنجليزية) ترجع قائمة المفاتيح الموجودة في القاموس. في الحقيقة ، إنها ليست قائمة كاملة (حاول كتابة fruits.keys() في المترجم الفوري الخاص بك) لكنها سلسلة يتم اجتيازها مثل القائمة.

تصفح القيم


يمكنك أيضًا تصفح القيم الموجودة في القاموس. للقيام بذلك ، نستخدم الطريقة values ( "القيم" باللغة الإنجليزية) .


>>> fruits = {"pommes":21, "melons":3, "poires":31}
>>> for valeur in fruits.values():
...     print(valeur)
... 
3
31
21
>>>
 
نادرًا ما تُستخدم هذه الطريقة للتصفح لأنه الأكثر عملية هو تصفح قائمة المفاتيح ، وهذا يكفي للحصول على القيم المقابلة. ولكن يمكننا بالطبع استخدامها بشرط واحد:


>>> if 21 in fruits.values():
...     print("واحدة من الثمار في الكمية 21.")
... 
واحدة من الثمار في الكمية 21.
>>>
 

تصفح المفاتيح والقيم في وقت واحد


للحصول على المؤشرات وكائنات القائمة في نفس الوقت ، نستخدم الوظيفة enumerate ، وآمل أن تتذكرها. لفعل الشيء نفسه مع القواميس ، نستخدم الطريقة items . تقوم بإرجاع قائمة تحتوي على الأزواج key : value في شكل واحد tuple . دعونا نرى كيفية استخدامها:


>>> fruits = {"pommes":21, "melons":3, "poires":31}
>>> for cle, valeur in fruits.items():
...     print("La clé {} contient la valeur {}.".format(cle, valeur))
... 
La clé melons contient la valeur 3.
La clé poires contient la valeur 31.
La clé pommes contient la valeur 21.
>>>
 
في بعض الأحيان يكون من الملائم جدًا تصفح القاموس باستخدام مفاتيحه والقيم المرتبطة به.

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

لا يزال لدينا القليل من الوظائف الإضافية لنراها وسننتهي من القواميس.

القواميس والمعلمات الوظيفية


ألا يذكرك هذا بشيء؟ اظن انه رأينا شيئًا مشابهًا في الفصل السابق.

إذا كنت تتذكر ، فقد اعترضنا بنجاح جميع معلمات الوظيفة ... باستثناء المعلمات المسماة.

استرجع المعلمات المسماة في قاموس


هناك أيضًا طريقة لالتقاط المعلمات المسماة للدالة. ومع ذلك ، في هذه الحالة ، يتم وضعها في قاموس. إذا قمت ، على سبيل المثال ، باستدعاء الوظيفة على النحو التالي :  fonction(parametre='a') سيكون لديك ، في القاموس يلتقط المعلمات المسماة ، مفتاح 'parametre'مرتبط بالقيمة 'a' . انظر بدلاً من ذلك:


>>> def fonction_inconnue(**parametres_nommes):
...     """ وظيفة تسمح بمعرفة كيفية استرداد المعلمات المسماة
...     ...     في قاموس """
...     
...     
...     print("تلقيت في المعلمات المسماة : {}.".format(parametres_nommes))
... 
>>> fonction_inconnue() # لا توجد معلمات
تلقيت في المعلمات المسماة: {}
>>> fonction_inconnue(p=4, j=8)
تلقيت في المعلمات المسماة: {'p': 4, 'j': 8}
>>>
 
لالتقاط جميع المعلمات المسماة غير المحددة في قاموس ، ضع نجمتين ** قبل اسم المعلمة.

إذا قمت بتمرير معلمات غير مسماة لهذه الوظيفة ، فإن Python ستطرح استثناءً.

لذلك ، للحصول على وظيفة تقبل أي نوع من المعلمات ، سواء أكانت مسماة أم لا ، بأي ترتيب ، وبأي كمية ، عليك التصريح عنها بهذه الطريقة:


def fonction_inconnue(*en_liste, **en_dictionnaire):
 
سيتم العثور على جميع المعلمات غير المسماة في المتغير en_liste والمعلمات المسماة في المتغير en_dictionnaire .
ولكن ما فائدة وجود وظيفة تقبل أي معلمة؟

في الوقت الحالي ، ليس كثيرًا لكنه سيأتي. عندما نقترب من الفصل الخاص بالديكور ، ستتذكره ويمكنك تهنئة نفسك بمعرفة هذه الميزة.

تحويل القاموس إلى معلمات مسماة للدالة


هنا مرة أخرى ، يمكننا أن نفعل العكس تمامًا: تحويل القاموس إلى معلمات مسماة للدالة. دعونا نرى مثالًا بسيطًا:


>>> parametres = {"sep":" >> ", "end":" -\n"}
>>> print("Voici", "un", "exemple", "d'appel", **parametres)
Voici >> un >> exemple >> d'appel -
>>>
 
يتم تمرير المعلمات المسماة إلى الوظيفة بواسطة قاموس. لإخبار Python أنه يجب تمرير القاموس كمعلمات مسماة ، وضعنا نجمتين قبل اسمه ** في استدعاء الوظيفة.

كما ترى ، يبدو الأمر كما كتبنا:


>>> print("Voici", "un", "exemple", "d'appel", sep=" >> ", end=" -\n")
Voici >> un >> exemple >> d'appel -
>>>
 
في الوقت الحالي ، يجب أن تجد أنه لا بأس في تعقيد حياتك مقابل القليل جدًا. سنرى في بقية هذه الدورة أن هذا ليس هو الحال ، في الواقع ، حتى لو لم نستخدم هذه الميزة كل يوم.

باختصار



  • القاموس هو كائن حاوية يربط المفاتيح بالقيم.
  • لإنشاء قاموس ، نستخدم بناء الجملة dictionnaire = {key1:value1, key2:velue2, keyN:valueN}.
  • يمكنك إضافة أو استبدال عنصر في القاموس:  dictionnaire[key] = value .
  • يمكنك إزالة مفتاح (وقيمته المقابلة) من القاموس باستخدام إما الكلمة الأساسية del أو الطريقة pop .
  • يمكنك تصفح القاموس باستخدام الطرق keys (  تصفح المفاتيح ) أو values (  تصفح القيم) أو items ( تصفح أزواج المفتاح والقيمة) .
  • يمكننا التقاط المعلمات المسماة التي تم تمريرها إلى وظيفة باستخدام هذا النحو
  •  def fonction_inconnue(**parametres_nommes) : (المعلمات المسماة موجودة في القاموس parametres_nommes ) .