Наряду со списками и кортежами Python имеет еще одну встроенную структуру данных, которая называется словарь (dictionary). В ряде языков программирования есть похожие структуры (словарь в C#, ассоциативный массив в PHP).
Как и список, словарь хранит коллекцию элементов. Каждый элемент в словаре имеет уникальный ключ, с которым ассоциировано некоторое значение.
Определение словаря имеет следующий синтаксис:
| 1 | dictionary = { ключ1:значение1, ключ2:значение2, ....} |
Определим пару словарей:
| 1 2 3 | users = {1: "Tom", 2: "Bob", 3: "Bill"} elements = {"Au": "Золото", "Fe": "Железо", "H": "Водород", "O": "Кислород"} |
В словаре users в качестве ключей используются числа, а в качестве значений — строки. В словаре element в качестве ключей используются строки.
Но необязательно ключи и строки должны быть однотипными. Они могу представлять разные типы:
| 1 | objects = {1: "Tom", "2": True, 3: 100.6} |
Мы можем также вообще определить пустой словарь без элементов:
| 1 | objects = {} |
или так:
| 1 | objects = dict() |
Преобразование из списка в словарь
Несмотря на то, что словарь и список — непохожие по структуре типы, но тем не менее существует возможности для отдельных видов списков преобразования их в словарь с помощью встроенной функции dict(). Для этого список должен хранить набор вложенных списков. Каждый вложенный список должен состоять из двух элементов — при конвертации в словарь первый элемент станет ключом, а второй — значением:
| 1 2 3 4 5 6 7 | users_list = [["+111123455", "Tom"],["+384767557", "Bob"],["+958758767", "Alice"]]users_dict = dict(users_list)print(users_dict) # {"+111123455": "Tom", "+384767557": "Bob", "+958758767": "Alice"} |
Подобным образом можно преобразовать в словарь двухмерные кортежи, которые в свою очередь содержать кортежи из двух элементов:
| 1 2 3 4 5 6 7 | users_tuple = (("+111123455", "Tom"),("+384767557", "Bob"),("+958758767", "Alice"))users_dict = dict(users_tuple)print(users_dict) |
Получение и изменение элементов
Для доступа к элементам словаря необходимо использовать ключ:
| 1 | dictionary[ключ] |
Например, получим и изменим элементы в словаре:
| 1 2 3 4 5 6 7 8 9 10 11 12 | users = {"+11111111": "Tom","+33333333": "Bob","+55555555": "Alice"} # получаем элемент с ключом "+11111111"print(users["+11111111"]) # Tom# установка значения элемента с ключом "+33333333"users["+33333333"] = "Bob Smith"print(users["+33333333"]) # Bob Smith |
Если при установки значения элемента с таким ключом в словаре не окажется, то произойдет его добавление:
| 1 | users["+4444444"] = "Sam" |
Но если мы попробуем получить значение с ключом, которого нет в словаре, то Python сгенерирует ошибку KeyError:
| 1 | user = users["+4444444"] # KeyError |
И чтобы предупредить эту ситуацию перед обращением к элементу мы можем проверять наличие ключа в словаре с помощью выражения ключ in словарь. Если ключ имеется в словаре, то данное выражение возвращает True:
| 1 2 3 4 5 6 | key = "+4444444"if key in users:user = users[key]print(user)else:print("Элемент не найден") |
Также для получения элементов можно использовать метод get, который имеет две формы:
get(key): возвращает из словаря элемент с ключом key. Если элемента с таким ключом нет, то возвращает значение Noneget(key, default): возвращает из словаря элемент с ключом key. Если элемента с таким ключом нет, то возвращает значение по умолчанию default
| 1 2 3 | key = "+55555555"user = users.get(key)user = users.get(key, "Unknown user") |
Удаление
Для удаления элемента по ключу применяется оператор del:
| 1 2 3 4 5 6 7 8 | users = {"+11111111": "Tom","+33333333": "Bob","+55555555": "Alice"} del users["+55555555"]print(users) |
Но стоит учитывать, что если подобного ключа не окажется в словаре, то будет выброшено исключение KeyError. Поэтому опять же перед удалением желательно проверять наличие элемента с данным ключом.
| 1 2 3 4 5 6 7 | key = "+55555555"if key in users:user = users[key]del users[key]print(user, "удален")else:print("Элемент не найден") |
Другой способ удаления представляет метод pop(). Он имеет две формы:
pop(key): удаляет элемент по ключу key и возвращает удаленный элемент. Если элемент с данным ключом отсутствует, то генерируется исключение KeyErrorpop(key, default): удаляет элемент по ключу key и возвращает удаленный элемент. Если элемент с данным ключом отсутствует, то возвращается значение default
| 1 2 3 4 5 6 7 8 9 10 11 | users = {"+11111111": "Tom","+33333333": "Bob","+55555555": "Alice"}key = "+55555555"user = users.pop(key)print(user)user = users.pop("+4444444", "Unknown user")print(user) |
Если необходимо удалить все элементы, то в этом случае можно воспользоваться методом clear():
| 1 | users.clear() |
Копирование и объединение словарей
Метод copy() копирует содержимое словаря, возвращая новый словарь:
| 1 2 | users = {"+1111111": "Tom","+3333333": "Bob","+5555555": "Alice"}users2 = users.copy() |
Метод update() объединяет два словаря:
| 1 2 3 4 5 6 7 | 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, в который добавляются элементы другого словаря. Но если необходимо, чтобы оба исходных словаря были без изменений, а результатом объединения был какой-то третий словарь, то можно предварительно скопировать один словарь в другой:
| 1 2 | users3 = users.copy()users3.update(users2) |
Перебор словаря
Для перебора словаря можно воспользоваться циклом for:
| 1 2 3 4 5 6 7 | users = {"+11111111": "Tom","+33333333": "Bob","+55555555": "Alice"}for key in users:print(key, " - ", users[key]) |
При переборе элементов мы получаем ключ текущего элемента и по нему можем получить сам элемент.
Другой способ перебора элементов представляет использование метода items():
| 1 2 | for key, value in users.items():print(key, " - ", value) |
Метод items() возвращает набор кортежей. Каждый кортеж содержит ключ и значение элемента, которые при переборе мы тут же можем получить в переменные key и value.
Также существуют отдельно возможности перебора ключей и перебора значений. Для перебора ключей мы можем вызвать у словаря метод keys():
| 12 | for key in users.keys():print(key) |
Правда, этот способ перебора не имеет смысла, так как и без вызова метода keys() мы можем перебрать ключи, как было показано выше.
Для перебора только значений мы можем вызвать у словаря метод values():
| 1 2 | for value in users.values():print(value) |
Комплексные словари
Кроме простейших объектов типа чисел и строк словари также могут хранить и более сложные объекты — те же списки, кортежи или другие словари:
| 1 2 3 4 5 6 7 8 9 10 11 | users = {"Tom":{"phone": "+971478745","email":"tom12@gmail.com"},"Bob": {"phone":"+876390444","email":"bob@gmail.com""skype":"bob123"}} |
В данном случае значение каждого элемента словаря в свою очередь представляет отдельный словарь.
Для обращения к элементам вложенного словаря соответственно необходимо использовать два ключа:
| 1 2 | old_email = users["Tom"]["email"]users["Tom"]["email"] = "supertom@gmail.com" |
Но если мы попробуем получить значение по ключу, который отсутствует в словаре, Python сгенерирует исключение KeyError:
| 1 | tom_skype = users["Tom"]["skype"] # KeyError |
Чтобы избежать ошибки, можно проверять наличие ключа в словаре:
| 1 2 3 4 5 | key = "skype"if key in users["Tom"]:print(users["Tom"]["skype"])else:print("skype is not found") |
Во всем остальном работа с комплексными и вложенными словарями аналогична работе с обычными словарями.