8  القاموس

flowchart TD
    Collection[<b>الجمع</b> <br> <code>Collection</code>]
    Collection --> Mapping[<b>الاقتران</b> <br> <code>Mapping</code>]
    Mapping --> MutableMapping[<b>الاقتران المتغير</b> <br> <code>MutableMapping</code>]
    MutableMapping --> dict[<b>القاموس</b> <br> <code>dict</code>]
شكل 8.1: شجرة أنواع القاموس

وراجع خريطة المجموعات: شكل 1

القاموس (dict) جمع متغير مرتب، العنصر فيه مرقوم فريد مقابل لقيمة.

تنشأ المجموعة الرابطة بالإجراء المنشئ dict() أو بالقوسين المتعرجين {} وذلك على النحو التالي:

d = {'key1': 'value1', 'key2': 'value2'}
d1 = dict(key1='value1', key2='value2')
d2 = dict([('key1', 'value1'), ('key2', 'value2')])
assert d == d1 == d2

وفي كل اقتران نضيفه إلى قائمة الاقتران (القاموس):

يستعمل القاموس في كثير من السياقات في البرمجة، وهو من أهم هياكل البيانات.

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

الكلمة ومعناها

القاموس بالمعنى الذي يشير إليه اللفظ. نفترض أن لدينا قاموسًا يحتوي على ترجمة بعض الكلمات من الإنجليزية إلى العربية:

english_to_arabic = {
    'apple': 'تفاحة',
    'banana': 'موزة',
    'orange': 'برتقالة',
}

ربط الأسماء بالأرقام

مثلاً: دليل أرقام الهواتف هو قاموس:

name_to_phone = {
    'Adam': '966xxxxxxxxx',
    'Mohammed': '966xxxxxxxxx',
}

دليل أسماء النطاقات

وكذلك دليل أسماء النطاقات (DNS: Domain Name System) على شبكة الانرتنت هو قاموس:

domain_to_ip = {
    'google.com': '172.217.14.206',
    'wikipedia.org': '103.86.96.10',
}

اختصار الروابط الطويلة

من استعمالات القاموس: اختصار الروابط الطويلة في روابط قصيرة.

short_to_full = {
    'google': 'https://www.google.com',
    'python': 'https://www.python.org',
    'wiki': 'https://www.wikipedia.org',
}

الكلمات المختصرة

أو الاختصارات إلى الكلمة التامة:

abb_to_full = {
    'ASAP': 'As Soon As Possible',
    'BRB': 'Be Right Back',
    'DIY': 'Do It Yourself',
    'EDA': 'Exploratory Data Analysis',
    'FYI': 'For Your Information',
    'SAR': 'Saudi Riyal',
}

القاموس (dict)

ومن حيث كون القاموس من نوع الجمع (Collection)، فإنه يقبل الإجراءات ثلاثة:

  • العضوية: x not in d
  • العد: len(d)
  • التكرار: for x in d

ويقبل القاموس لكونه اقترانًا (Mapping) الإجراءات التالية:

  • الإشارة مفتاح: dict[key]
  • الإشارة بمفتاح مع الرجوع بقيمة ابتدائية إن لم يُعثَر عليه: dict.get(key[, default])

ولكونه اقترانًا متغيرًا (MutableMapping)، فإنه يقبل الإجراءات التالية:

  • التعديل بمفتاح: dict[key] = value
  • الحذف بمفتاح: del dict[key]
  • نزع بمفتاح وإرجاع القيمة: x = dict.pop(key)
  • التحديث: dict.update(mapping)

راجع خريطة الجموع: شكل 1.

وهذه كذلك، كلها مرقومات، ولا يشترط أن تكون متجانسة (من نفس النوع)، كما يلي:

data = {
    'key1': 100,
    20: 'value2',
    'c': [10, 20, 30, True],
    (1, 2): 'value3',
    ('a', 'b', 'c'): 'value4',
}

assert len(data) == 5
del data['key1']
assert 'key1' not in data

ونحصل عليها بالإشارة بمرقوم:

print(data[20])
print(data['c'])
print(data[(1, 2)])
print(data[('a', 'b', 'c')])
value2
[10, 20, 30, True]
value3
value4

التضمين

يجوز جعل القيمة نفسها قاموسًا. ومثال ذلك حفظ اختيارات المستخدم هكذا:

user = {
    'name': 'Adam',
    'language': 'Arabic',
    'phone': '966xxxxxxxxx',
    'last_updated': '2021-09-01',
    'age': 25,
    'notifications': {
        'email': True,
        'sms': False,
        'push': True
    },
    'emails': ['example1@domain.com', 'example2@domain.com']
}

وللوصول إلى قيمة مضمَّنة، نستعمل الإشارة بالمفتاح مرتين، هكذا:

user['notifications']['push']
True

التكرار

ويجوز التكرار بثلاثة طرق:

  • كر العناصر: for key, value in d.items()
  • كر المفاتيح: for key in d.keys()
  • كر القيم: for value in d.values()

مثال:

d = {
    'A': 'Salam',
    'B': 'Hello',
    'C': 'Hi',
}
for value in d.values():
    print(value)
Salam
Hello
Hi

عكس القاموس

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

d = {
    'ASAP': 'As soon as possible',
    'TBD': 'To be determined',
    'IDK': 'I don\'t know',
}
inverse = dict()
for k, v in d.items():
    inverse[v] = k
inverse
{'As soon as possible': 'ASAP',
 'To be determined': 'TBD',
 "I don't know": 'IDK'}

أو بالجملة المختصرة:

inverse = {v: k for k, v in d.items()}
inverse
{'As soon as possible': 'ASAP',
 'To be determined': 'TBD',
 "I don't know": 'IDK'}

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

ويتحصل القاموس من سلسلتين باستعمال الإجراء zip()، كما يلي:

students = ['Ahmad', 'Belal', 'Camal', 'Dawood']
marks    = [     90,      80,      75,       85]
data = dict(zip(students, marks))
data
{'Ahmad': 90, 'Belal': 80, 'Camal': 75, 'Dawood': 85}