ال

القواميس في Python

37 تمرينًا

نبذة عن القواميس

القاموس (dict) في Python هو بنية بيانات تربط المفاتيح القابلة للتجزئة بـ القيم، ويُعرف في لغات البرمجة الأخرى باسم جدول التجزئة القابل لتغيير الحجم، أو hashmap، أو المصفوفة الترابطية. القواميس هي نوع الربط الوحيد المدمج في Python.

يجب أن تكون keys قابلة للتجزئة وفريدة في القاموس بأكمله. يمكن أن تشمل أنواع المفاتيح numbers، وstrs، وtuples (من القيم غير القابلة للتغيير). ولا يمكنها أن تحتوي على بنى بيانات قابلة للتغيير مثل lists أو dicts أو sets. بدءًا من Python 3.7، يُضمن أن يكون ترتيب مفاتيح dict هو ترتيب إدخال المدخلات.

يمكن أن تكون values من أي نوع أو بنية بيانات. كما يمكن للقيم أن تتداخل بشكل تعسفي، بحيث يمكن أن تشمل مصفوفات من مصفوفات، وقواميس فرعية، وبنى بيانات أخرى مخصصة أو مركبة.

عند إعطاء key، تستطيع القواميس استرجاع value في زمن ثابت (في المتوسط) (بغض النظر عن عدد المدخلات). وبالمقارنة بالبحث عن قيمة داخل list أو array (دون معرفة موضع index)، يستهلك dict ذاكرة أكبر بكثير، لكن استرجاعه سريع جدًا.

القواميس مفيدة بشكل خاص في السيناريوهات التي تكون فيها مجموعة العناصر كبيرة ويجب الوصول إليها وتحديثها بشكل متكرر.

إنشاء القاموس

يمكن إنشاء القواميس بطرق مختلفة عديدة، منها:

  • استخدام طريقة الصنف fromkeys().
  • استخدام استيعابات القواميس.
  • دمج قاموسين عبر فك الحزم (**).
  • دمج القواميس عبر العامل | (التحديث).
  • استخدام حلقة لإضافة مدخلات بشكل متكرر إلى dict فارغ أُنشئ مسبقًا.

أكثر طريقتين مباشرتين هما مُنشئ القاموس و_القيمة الحرفية_ للقاموس.

مُنشئ القاموس

يمكن استخدام dict() (مُنشئ الصنف dict) مع أي كائن قابل للتكرار من أزواج key وvalue. كما يمكن استدعاؤه بسلسلة من الوسائط بالشكل <name>=<value>:

# Passing a list of key,value tuples.
>>> wombat = dict([('name', 'Wombat'),
...              ('speed', 23),
...              ('land_animal', True)])
{'name': 'Wombat', 'speed': 23, 'land_animal': True}


# Using key=value arguments.
>>> bear = dict(name="Black Bear",
...             speed=40,
...             land_animal=True)
{'name': 'Black Bear', 'speed': 40, 'land_animal': True}

يوضح التوثيق الخاص بـ dicts تنويعات وخيارات إضافية في استخدام المُنشئ.

القواميس الحرفية

يمكن أيضًا إدخال القاموس مباشرة كـ قيمة حرفية للقاموس، باستخدام الأقواس المعقوفة ({}) التي تحيط بأزواج key : value. ويمكن أن تظهر المدخلات المحاطة بـ {} على أسطر منفصلة أيضًا:

>>> whale = {"name": "Blue Whale", 
             "speed": 35, 
             "land_animal": False}
{'name': 'Blue Whale', 'speed': 35, 'land_animal': False}

>>> wombat = {'name': 'Wombat',
              'speed': 23,
              'land_animal': True,
              'color': 'Brindle'}

>>> wombat
{'name': 'Wombat', 'speed': 23, 'land_animal': True, 'color': 'Brindle'}

القواميس المتداخلة

يمكن أن تتداخل القواميس بشكل تعسفي:

animals = {
    "Real" : {
        "Winged" : {
            "Sparrow" : {'name': 'sparrow','speed': 12, 'land_animal': True},
            "Kestrel" : {'name': 'kestrel', 'speed': 15, 'land_animal': True}
           },
        "Legged" : {
            "Wombat" : {'name': 'Wombat', 'speed': 23, 'land_animal': True},
            "Black Bear": {'name': 'Black Bear', 'speed': 40, 'land_animal': True},
            "Polecat" : {'name': 'Polecat', 'speed': 15, 'land_animal': True}
           },
        "Other" :  {
            "Whale" : {'name': 'Blue Whale', 'speed': 35, 'land_animal': False},
            "Orca" : {'name': 'Orca', 'speed': 45, 'land_animal': False},
            "Snake" : {'name': 'Python', 'speed': 25, 'land_animal': True}
            }
        },
        
    "Imaginary": {
        "Winged" : {
            "Dragon" : {'name': 'Fire Dragon','speed': 100, 'land_animal': True},
            "Phoenix" : {'name': 'Phoenix', 'speed': 1500, 'land_animal': True}
            },
        "Legged" : {
            "Sphinx" : {'name': 'Sphinx','speed': 10, 'land_animal': True},
            "Minotaur" : {'name': 'Minotaur', 'speed': 5, 'land_animal': True}
            },
        "Other" :  {}
        }
   }

الوصول إلى القيم في dict

يمكنك الوصول إلى value في قاموس باستخدام مفتاح بين الأقواس المربعة. إذا لم يكن المفتاح موجودًا في القاموس، فسيُرفع KeyError:

>>> bear["speed"]
40

>>> bear["color"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'color'

يمكن تجنب KeyError بالوصول إلى مدخل عبر الطريقة get(<key>, <default value>):

>>> bear.get("color", 'not found')
'not found'

الوصول إلى مدخلات القواميس المتداخلة

للوصول إلى المدخلات في القواميس المتداخلة، استخدم أقواسًا متتالية. إذا كان مفتاح معين مفقودًا، فسيُرفع KeyError المعتاد:

# Using the animals nested dictionary.
>>> animals["Real"]["winged"]["Kestrel"]["speed"]
15

>>> animals["Imaginary"]["winged"]["Kestrel"]["speed"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'Kestrel'

لتجنب KeyError، يمكن استخدام .get()، لكن الاستدعاءات إلى .get() يجب أن تكون متسلسلة:

# Using the animals nested dictionary.
# Note the use of parenthesis to enable placing the 
# .get() calls on separate lines.
>>> (animals.get("Imaginary", {})
            .get("Legged", {})
            .get("Sphinx", {})
            .get("Color", "I have no idea!"))
'I have no idea!'

تغيير قيم القاموس أو إضافتها

يمكنك تغيير value مدخل عبر الإسناد إلى مفتاحه:

# Assigning the value "Grizzly Bear" to the name key.
>>> bear["name"] = "Grizzly Bear"
{'name': 'Grizzly Bear', 'speed': 40, 'land_animal': True}

>>> whale["speed"] = 25
{'name': 'Blue Whale', 'speed': 25, 'land_animal': False}

يمكن إضافة أزواج key:value جديدة بالطريقة نفسها:

# Adding a new "color" key with a new "tawney" value.
>>> bear["color"] = 'tawney'
{'name': 'Grizzly Bear', 'speed': 40, 'land_animal': True, 'color': 'tawney'}

>>> whale["blowholes"] = 1
{'name': 'Blue Whale', 'speed': 25, 'land_animal': False, 'blowholes': 1}

إزالة مدخلات القاموس (بـ pop وبـ del)

يمكنك استخدام الطريقة <dict>.pop(<key>) لحذف مدخل من القاموس. تزيل <dict>.pop() الزوج (key, value) وتُرجع value للاستخدام. ومثل <dict>.get()، تقبل <dict>.pop(<key>) وسيطًا ثانيًا (<dict>.pop(<key>, <default value>)) سيُرجَع إذا لم يُعثر على key. وهذا يمنع رفع KeyError:

# Using .pop() removes both the key and value, returning the value.
>>> bear.pop("name")
'Grizzly Bear'


# The "name" key is now removed from the dictionary.
# Attempting .pop() a second time will throw a KeyError.
>>> bear.pop("name")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'name'


# Using a default argument with .pop() will 
# prevent a KeyError from a missing key.
>>> bear.pop("name", "Unknown")
'Unknown'

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

>>> wombat = {'name': 'Wombat',
              'speed': 23,
              'land_animal': True,
              'color': 'Brindle',
              'talent': 'Singing',
              'size': 'small'}

# Remove a single entry from the dictionary.
>>> del wombat["color"]
>>> wombat
{'name': 'Wombat', 'speed': 23, 'land_animal': True, 'talent': 'Singing', 'size': 'small'}


# Remove multiple entries from the dictionary.
>>> del wombat["talent"], wombat["size"]
>>> wombat
{'name': 'Wombat', 'speed': 23, 'land_animal': True}


# Attempting a deletion of a non-existent key raises a KeyError
>>> del wombat["number_of_legs"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'number_of_legs'

المرور على القاموس والتكرار خلاله

التكرار خلال قاموس باستخدام for item in dict أو while item يمر على المفاتيح افتراضيًا. يمكنك الوصول إلى القيم ضمن الحلقة نفسها باستخدام الأقواس المربعة:

>>> for key in bear:
...     print((key, bear[key])) # <--This prints a tuple of (key, value).
('name', 'Black Bear')
('speed', 40)
('land_animal', True)

يمكنك أيضًا استخدام الطريقة .items()، التي تُرجع صفوفًا (key, value):

# dict.items() forms (key, value tuples) that can be 
# unpacked and iterated over.
>>> for key, value in whale.items():
...     print(key, ":", value)
name : Blue Whale
speed : 25
land_animal : False
blowholes : 1

وبالمثل، ستُرجع .keys() المفاتيح keys، وستُرجع .values() القيم values.

للحصول على شرح مفصل للقواميس في Python، يُعد التوثيق الرسمي نقطة بداية ممتازة، أو يمكنك أيضًا الاطلاع على درس W3-Schools.

توسيع وظائف القاموس: وحدة collections

تضيف وحدة collections وظائف متخصصة إلى أنواع البيانات القياسية القائمة على المجموعات في Python (dict، set، list، tuple). من أكثر الأصناف المفيدة القائمة على القواميس ثلاثة:

  • Counter يعد العناصر تلقائيًا ويُرجعها في dict مع العناصر كمفاتيح وعددها كقيم.
  • OrderedDict لديه طرق متخصصة في ترتيب مدخلات القاموس.
  • defaultdict يستخدم طريقة مصنع لضبط قيمة افتراضية إذا لم يُعثر على key عند محاولة استرجاع مدخل من القاموس أو الإسناد إليه.
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة

تعلّم القواميس

التدريب مقفل

افتح 4 تمارين إضافية لممارسة القواميس