Словники Python

Поряд зі списками і кортежами Python має ще одну вбудовану структуру даних, яка називається словник (dictionary). У ряді мов програмування є схожі структури (словник в C#, асоціативний масив в PHP).

Як і список, словник зберігає колекцію елементів. Кожен елемент в словнику має унікальний ключ, з яким асоційовано деяке значення.

Визначення словника має наступний синтаксис:

dictionary = { ключ1:значення1, ключ2:значення2, ....}  

Визначимо пару словників:

users = {1: "Tom", 2: "Bob", 3: "Bill"}     

elements = {"Au": "Золото", "Fe": "Залізо", "H": "Водень", "O": "Кисень"} 

У словнику users в якості ключів використовуються числа, а в якості значень - рядки. У словнику element в якості ключів використовуються рядки.

Але необов'язково ключі і рядки повинні бути однотипними. Вони можуть представляти різні типи:

objects = {1: "Tom", "2": True, 3: 100.6}  

Ми можемо також взагалі визначити порожній словник без елементів:

objects = {}    

#або так:    

objects = dict() 

Перетворення зі списку в словник

Незважаючи на те, що словник і список - несхожі за структурою типи, але тим не менше існує можливості для окремих видів списків, перетворення їх в словник з допомогою вбудованої функції dict(). Для цього список повинен зберігати набір вкладених списків. Кожен вкладений список повинен складатися з двох елементів - при конвертації в словник перший елемент стане ключем, а другий - значенням:

users_list = [  
    ["+111123455", "Tom"],  
    ["+384767557", "Bob"],  
    ["+958758767", "Alice"]  
]  

users_dict = dict(users_list)  
print(users_dict) # {"+111123455": "Tom", "+384767557": "Bob", "+958758767": "Alice"}

Подібним чином можна перетворити в словник двомірні кортежі, які в свою чергу містити кортежі з двох елементів:

users_tuple = (  
    ("+111123455", "Tom"),  
    ("+384767557", "Bob"),  
    ("+958758767", "Alice")  
)  

users_dict = dict(users_tuple)  
print(users_dict)

Отримання та зміна елементів

Для доступу до елементів словника необхідно використовувати ключ:

dictionary[ключ]  

Наприклад, отримаємо і змінимо елементи в словнику:

users = {  
    "+11111111": "Tom",  
    "+33333333": "Bob",  
    "+55555555": "Alice"  
}     

# отримуємо елемент з ключем "+11111111"  
print(users["+11111111"]) # Tom     

# установка значення елемента з ключем "+33333333"  
users["+33333333"] = "Bob Smith"  
print(users["+33333333"]) # Bob Smith  

Якщо при установки значення елемента з таким ключем в словнику не виявиться, то відбудеться його додавання:

users["+4444444"] = "Sam"  

Але якщо ми спробуємо отримати значення з ключем, якого немає в словнику, то Python згенерує помилку KeyError:

user = users["+4444444"] # KeyError  

І щоб попередити цю ситуацію перед зверненням до елемента ми можемо перевіряти наявність ключа в словнику за допомогою виразу ключ in словник. Якщо ключ є в словнику, то даний вираз повертає True:

key = "+4444444"  
if key in users:  
    user = users[key]  
    print(user)  
else:  
    print("Елемент не знайдено") 

Також для отримання елементів можна використовувати метод get, який має дві форми:

  • get (key): повертає з словника елемент з ключем key. Якщо елемента з таким ключем немає, то повертає значення None
  • get (key, default): повертає з словника елемент з ключем key. Якщо елемента з таким ключем немає, то повертає значення за замовчуванням default
key = "+55555555"  
user = users.get(key)  
user = users.get(key, "Unknown user") 

Видалення

Для видалення елемента по ключу застосовується оператор del:

users = {  
    "+11111111": "Tom",  
    "+33333333": "Bob",  
    "+55555555": "Alice"  
}  

del users["+55555555"]  
print(users) 

Але варто враховувати, що якщо подібного ключа не виявиться в словнику, то буде викинуто виняток KeyError. Тому знову ж перед видаленням бажано перевіряти наявність елемента з даним ключем.

key = "+55555555"  
if key in users:  
    user = users[key] 
    del users[key]  
    print (user, " видалено")  
else:  
    print("Елемент не знайдено") 

Інший спосіб видалення представляє метод pop(). Він має дві форми:

  • pop (key): видаляє елемент за ключем key і повертає видалений елемент. Якщо елемент з даним ключем відсутній, то генерується виняток KeyError
  • pop (key, default): видаляє елемент за ключем key і повертає видалений елемент. Якщо елемент з даним ключем відсутній, то повертається значення default
users = {  
    "+11111111": "Tom",  
    "+33333333": "Bob",  
    "+55555555": "Alice" 
}  
key = "+55555555"  
user = users.pop(key)  
print(user)    

user = users.pop("+4444444", "Unknown user")  
print(user)  

Якщо необхідно видалити всі елементи, то в цьому випадку можна скористатися методом clear():

users.clear()  

Копіювання та об'єднання словників

Метод copy() копіює вміст словника, повертаючи новий словник:

users = {"+1111111": "Tom","+3333333": "Bob","+5555555": "Alice"}  
users2 = users.copy() 

Метод update() об'єднує два словника:

users = {"+1111111": "Tom","+3333333": "Bob","+5555555": "Alice"}     

users2 = {"+2222222": "Sam","+6666666": "Kate"}  
users.update(users2)     

print(users) # {"+1111111": "Tom", "+3333333": "Bob", "+5555555": "Alice", "+2222222": "Sam", "+6666666": "Kate"} 
print(users2) # {"+2222222": "Sam", "+6666666": "Kate"}  

При цьому словник users2 залишається без змін. Змінюється словник users, в який додаються елементи іншого словника. Але якщо необхідно, щоб обидва вихідних словника були без змін, а результатом об'єднання був якийсь третій словник, то можна попередньо скопіювати один словника в іншій:

users3 = users.copy()  
users3.update(users2) 

Перебір словника

Для перебору словника можна скористатися циклом for:

users = {  
    "+11111111": "Tom",  
    "+33333333": "Bob",  
    "+55555555": "Alice"  
}  
for key in users:  
    print(key, " - ", users[key]) 

При переборі елементів ми отримуємо ключ поточного елемента і по ньому можемо отримати сам елемент.

Інший спосіб перебору елементів представляє використання методу items():

for key, value in users.items():  
    print(key, " - ", value)  

Метод items() повертає набір кортежів. Кожен кортеж містить ключ і значення елемента, які при переборі ми можемо отримати в змінні key і value.

Також існують окремо можливості перебору ключів і перебору значень. Для перебору ключів ми можемо викликати у словника метод keys():

for key in users.keys():  
    print(key) 

Правда, цей спосіб перебору не має сенсу, так як і без виклику методу keys() ми можемо перебрати ключі, як було показано вище.

Для перебору тільки значень ми можемо викликати у словника метод values():

for value in users.values():  
    print(value)  

Комплексні словники

Крім найпростіших об'єктів типу чисел і рядків словники також можуть зберігати і більш складні об'єкти - ті ж списки, кортежі або інші словники:

users = {  
    "Tom": {  
        "phone": "+971478745",  
        "email": "tom12@gmail.com"  
    },  
    "Bob": {  
        "phone": "+876390444",  
        "email": "bob@gmail.com",  
        "skype": "bob123"  
    }  
}  

В даному випадку значення кожного елемента словника в свою чергу представляє окремий словник.

Для звернення до елементів вкладеного словника відповідно необхідно використовувати два ключа:

old_email = users["Tom"]["email"]  
users["Tom"]["email"] = "supertom@gmail.com"  

Але якщо ми спробуємо отримати значення за ключем, який відсутній у словнику, Python генерує виняток KeyError:

tom_skype = users["Tom"]["skype"] # KeyError  

Щоб уникнути помилки, можна перевіряти наявність ключа в словнику:

key = "skype"  
if key in users["Tom"]:  
    print(users["Tom"]["skype"])  
else:  
    print("skype is not found") 

У всьому іншому робота з комплексними і вкладеними словниками аналогічна роботі зі звичайними словниками.