Словарь (dictionary или dict) — это неупорядоченная (в отличие от списка) структура данных в языке программирования Python, которая имеет вид «ключ — значение».
Говоря проще, любой словарь напоминает записную книжку без определенного порядка, где каждый номер (значение) соотнесен с конкретным именем (ключ).
Виктор |
+7 905 600 50 40 |
Юлия |
+7 960 540 43 32 |
Александр |
+7 960 830 72 61 |
Каждый ключ в словаря полностью уникален, а вот сами значения могут повторяться.
То есть, если добавить в таблицу выше новый номер (ключ) с именем «Юлия» (значение), то запись не будет дублироваться, а обновится уже существующее значение.
При этом, чтобы узнать номер определенного человека, нужно указать его имя. Таким образом словарь в Python упрощает поиск в структурах с большим объемом данных.
Ключами могут выступать следующие типы данных:
строки,
числа (целые и дробные),
кортежи.
В качестве значения можно использовать любой тип данных — в том числе другие словари и списки.
В этом руководстве используется Python версии 3.10.12.
Наиболее простой и наглядный способ создать словарь — использовать фигурные скобки.
Например, так можно создать пустой словарь без ключей и значений:
empty_dictionary = {}
А вот так создается словарь с ключами и значениями внутри:
team_ages = {"Александр": 23, "Виктория": 43, "Евгений": 26, "Петр": 52, "Денис": 32}
Имена в кавычках — это ключи, а цифры — их значения.
Показанную ранее таблицу можно выразить в виде словаря следующим образом:
team_phones = {
"Виктор": "+7 905 600 50 40",
"Юлия": "+7 960 540 43 32",
"Александр": "+7 960 830 72 61"
}
В этом случае значения имеют строковый тип, а не числовой.
Кстати, вместо двойных кавычек можно использовать одинарные:
team_phones = {
'Виктор': '+7 905 600 50 40',
'Юлия': '+7 960 540 43 32',
'Александр': '+7 960 830 72 61'
}
Как и со многими другими типами переменных, словарь можно создать с помощью соответствующей ему функции.
Например, так создается пустой словарь:
just_dictionary = dict()
А так можно создать словарь с ключами и значениями:
keys_and_values = [("Александр", 23), ("Виктория",43), ("Евгений", 26), ("Петр", 52), ("Денис", 32)]
team_ages = dict(keys_and_values)
В этом случае сперва создается список с так называемыми кортежами — парами «ключ — значение».
Однако, есть и более лаконичный способ создать словарь через функцию:
team_ages = dict(Александр = 23, Виктория = 43, Евгений = 26, Петр = 52, Денис = 32)
Таким образом, каждый аргумент функции превращается в ключ со значением нового словаря.
Еще один способ создать словарь — преобразовать в него список. Здесь есть несколько нюансов:
Например, так можно создать словарь, у которого значения ключей будут пустыми:
team_names = ["Александр", "Виктория", "Евгений", "Петр", "Денис"] # список с ключами
team_ages = dict.fromkeys(team_names)
print(team_ages)
Консольный вывод будет следующий:
{'Александр': None, 'Виктория': None, 'Евгений': None, 'Петр': None, 'Денис': None}
А вот так создается словарь с указанием значения, которое будет общим для всех ключей:
team_names = ["Александр", "Виктория", "Евгений", "Петр", "Денис"]
team_ages = dict.fromkeys(team_names, 0) # указываем значение по умолчанию вторым аргументом
print(team_ages)
В этом случае консольный вывод будет таким:
{'Александр': 0, 'Виктория': 0, 'Евгений': 0, 'Петр': 0, 'Денис': 0}
Более нестандартный способ создания словаря — его генерация из других данных с помощью так называемого генератора словаря, представляющего собой компактный цикл for
, внутри которого прописываются правила генерации словаря.
Соответственно, цикл генератора итерирует по структуре данных, из которой создается этот словарь.
Например, вот так можно создать словарь из списка с общим значением для всех ключей:
team_names = ["Александр", "Виктория", "Евгений", "Петр", "Денис"]
team_ages = {name : 0 for name in team_names} # генератор словаря со числом в качестве значения по умолчанию
print(team_ages)
Консольный вывод будет аналогичным предыдущему:
{'Александр': 0, 'Виктория': 0, 'Евгений': 0, 'Петр': 0, 'Денис': 0}
Однако основное преимущество генератора словаря — возможность задавать индивидуальное значение для каждого ключа.
Для этого нужно подготовить два списка и несколько усложнить базовую запись генератора:
team_names = ["Александр", "Виктория", "Евгений", "Петр", "Денис"]
team_numbers = [23, 43, 26, 52, 32]
team_ages = {name : age for name, age in zip(team_names, team_numbers)} # используем вспомогательную функцию zip() для итерирования сразу двух листов
print(team_ages)
Функция zip()
преобразует два списка в список кортежей, по которому выполняется итерация в цикле генератора.
В этом случае вывод в терминале консоли будет следующим:
{'Александр': 23, 'Виктория': 43, 'Евгений': 26, 'Петр': 52, 'Денис': 32}
Есть также более сложный вариант, позволяющий сгенерировать словарь из одного списка, содержащего как ключи, так и значения:
team_data = ["Александр", 23, "Виктория", 43, "Евгений", 26, "Петр", 52, "Денис", 32] # ключи и значения последовательно записаны внутри одного списка
team_ages = {team_data[i] : team_data[i+1] for i in range(0, len(team_data), 2)} # продолжительность цикла равна длине списка, а шаг итерирования равен двум
print(team_ages)
В этом примере используется функция range()
, которая устанавливает длину и шаг итерирования в цикле.
Консольный вывод неотличим от предыдущих:
{'Александр': 23, 'Виктория': 43, 'Евгений': 26, 'Петр': 52, 'Денис': 32}
Добавить элемент в словарь можно с помощью указания ранее несуществующего ключа в квадратных скобках и нового значения:
team_ages = {"Александр": 23, "Виктория": 43, "Евгений": 26, "Петр": 52, "Денис": 32}
team_ages["Екатерина"] = 28 # записываем значение по новому ключу
print(team_ages)
Консольный вывод будет таким:
{'Александр': 24, 'Виктория': 43, 'Евгений': 26, 'Петр': 52, 'Денис': 32, 'Екатерина': 28}
Изменение элемента синтаксически не отличается от его добавления, за тем исключением, что элемент уже существует внутри словаря:
team_ages = {"Александр": 23, "Виктория": 43, "Евгений": 26, "Петр": 52, "Денис": 32}
team_ages["Виктория"] = 44 # обновляем уже существующее значение
print(team_ages)
Вывод в консольном терминале окажется таким:
{'Александр': 24, 'Виктория': 44, 'Евгений': 26, 'Петр': 52, 'Денис': 32}
Получить доступ к значениям словаря можно с помощью квадратных скобок с указанием ключа:
team_ages = {"Александр": 23, "Виктория": 43, "Евгений": 26, "Петр": 52, "Денис": 32}
print(team_ages["Евгений"])
Вывод в терминале консоли будет таким:
26
Либо более наглядный пример с ранее показанной таблицей:
team_phones = {
"Виктор": "+7 905 600 50 40",
"Юлия": "+7 960 540 43 32",
"Александр": "+7 960 830 72 61"
}
print(team_phones["Юлия"])
В этом случае консольный вывод будет следующим:
+7 960 540 43 32
Удалить элемент из словаря можно с помощью специального ключевого слова:
team_ages = {"Александр": 23, "Виктория": 43, "Евгений": 26, "Петр": 52, "Денис": 32}
del team_ages["Виктория"]
print(team_ages)
Соответственно, консольный вывод не будет содержать удаленный элемент:
{'Александр': 23, 'Евгений': 26, 'Петр': 52, 'Денис': 32}
У словаря есть набор специальных методов для управления элементами внутри — ключами и значениями. Многие из этих методов дублируют ранее показанные функции добавления, изменения и удаления.
Этот метод добавляет в словарь новые элементы путем передачи другого словаря в качестве аргумента:
team_ages = {"Александр": 23, "Виктория": 43, "Евгений": 26, "Петр": 52, "Денис": 32}
team_ages.update({
"Иван": 32,
"Екатерина": 28
})
print(team_ages)
В консоли появится следующий вывод:
{'Александр': 24, 'Виктория': 43, 'Евгений': 26, 'Петр': 52, 'Денис': 32, 'Иван': 32, 'Екатерина': 28}
Тот же самый результат можно получить, заранее создав словарь с добавляемыми элементами:
team_ages = {"Александр": 23, "Виктория": 43, "Евгений": 26, "Петр": 52, "Денис": 32}
team_add = {"Иван": 32, "Екатерина": 28}
team_ages.update(team_add)
print(team_ages)
Разумеется, вывод аналогичный:
{'Александр': 24, 'Виктория': 43, 'Евгений': 26, 'Петр': 52, 'Денис': 32, 'Иван': 32, 'Екатерина': 28}
Получить доступ к значению можно не только с помощью квадратных скобок, но и через соответствующую функцию:
team_ages = {"Александр": 23, "Виктория": 43, "Евгений": 26, "Петр": 52, "Денис": 32}
print(team_ages.get("Виктория"))
print(team_ages["Виктория"])
Оба консольных вывода будут одинаковые:
43
43
А вот что будет, если в качестве аргумента передать несуществующий ключ:
team_ages = {"Александр": 23, "Виктория": 43, "Евгений": 26, "Петр": 52, "Денис": 32}
print(team_ages.get("Анастасия"))
Консольный вывод будет уже таким:
None
Однако главная особенность get()
в отличие от квадратных скобок — возможность задать значение для несуществующего ключа в качестве второго аргумента:
team_ages = {"Александр": 23, "Виктория": 43, "Евгений": 26, "Петр": 52, "Денис": 32}
print(team_ages.get("Анастасия", "Несуществующий сотрудник"))
В этом случае консольный вывод станет таким:
Несуществующий сотрудник
При использовании квадратных скобок пришлось бы использовать блок обработки ошибок try / except
в тех случаях, когда нет уверенности в существовании ключа.
В словарях есть отдельная функция для удаления элемента по ключу:
team_ages = {"Александр": 23, "Виктория": 43, "Евгений": 26, "Петр": 52, "Денис": 32}
team_ages.pop("Александр")
print(team_ages)
Вывод в терминале консоли будет следующим:
{'Виктория': 43, 'Евгений': 26, 'Петр': 52, 'Денис': 32}
Вместо удаления конкретного элемента по ключу можно удалить последний добавленный:
team_ages = {"Александр": 23, "Виктория": 43, "Евгений": 26, "Петр": 52, "Денис": 32}
team_add = {"Иван": 32, "Екатерина": 28}
team_ages.update({"Иван": 32})
print(team_ages)
team_ages.popitem()
print(team_ages)
В терминале консоли появится как содержимое словаря с добавленным элементом, так и содержимое после его удаления:
{'Александр': 23, 'Виктория': 43, 'Евгений': 26, 'Петр': 52, 'Денис': 32, 'Иван': 32}
{'Александр': 23, 'Виктория': 43, 'Евгений': 26, 'Петр': 52, 'Денис': 32}
Словарь можно полностью очистить с помощью соответствующего метода:
team_ages = {"Александр": 23, "Виктория": 43, "Евгений": 26, "Петр": 52, "Денис": 32}
team_ages.clear()
print(team_ages)
В консольном выводе окажется пустой словарь:
{}
Словарь можно полностью скопировать:
team_ages = {"Александр": 23, "Виктория": 43, "Евгений": 26, "Петр": 52, "Денис": 32}
team_ages_copy = team_ages.copy()
print(team_ages)
print(team_ages_copy)
Консольный вывод будет содержать одинаковое содержимое двух разных словарей:
{'Александр': 23, 'Виктория': 43, 'Евгений': 26, 'Петр': 52, 'Денис': 32}
{'Александр': 23, 'Виктория': 43, 'Евгений': 26, 'Петр': 52, 'Денис': 32}
Механики добавления или извлечения ключа иногда недостаточно. Зачастую нужно более сложное поведение.
Например, в некоторых случаях необходимо проверить наличие ключа и сразу получить его значение, а если такого ключа нет — автоматически добавить его.
В Python для такой операции есть специальный метод:
team_ages = {"Александр": 23, "Виктория": 43, "Евгений": 26, "Петр": 52, "Денис": 32}
print(team_ages.setdefault("Александр")) # такой ключ уже есть
print(team_ages.setdefault("Иван")) # такого ключа еще нет, поэтому он будет создан со значением None
print(team_ages.setdefault("Екатерина", 29)) # такого ключа еще нет, поэтому он будет создан со значением 29
В терминале консоли появится вывод по всем запрашиваемым именам вне зависимости от того, существовали ли они в момент выполнения функции или нет:
23
None
29
Из словаря можно извлекать данные ключей и значений. Как правило такая операция извлечения выполняется для преобразования словаря в другой тип данных — например, список.
Для извлечения данных из словаря в языке программирования Python есть несколько функций:
dict.keys()
— возвращает объект с ключамиdict.values()
— возвращает объект со значениямиdict.items()
— возвращает объект с кортежами «ключ — значение»Вот пример того, как можно извлечь данные из словаря и преобразовать их в список:
team_phones = {
"Виктор": "+7 905 600 50 40",
"Юлия": "+7 960 540 43 32",
"Александр": "+7 960 830 72 61"
}
# все возвращаемые объекты конвертируются в списки через функцию list()
team_names = list(team_phones.keys()) # список с ключами словаря
team_numbers = list(team_phones.values()) # список со значениями словаря
team_all = list(team_phones.items()) # список с парами «ключ-значение» словаря
print(team_names)
print(team_numbers)
print(team_all)
Вывод в консольном терминале будет таким:
['Виктор', 'Юлия', 'Александр']
['+7 905 600 50 40', '+7 960 540 43 32', '+7 960 830 72 61']
[('Виктор', '+7 905 600 50 40'), ('Юлия', '+7 960 540 43 32'), ('Александр', '+7 960 830 72 61')]
В примере выше выполняется явная конвертация возвращаемых словарем объектов в списки.
Однако, это можно и не делать:
team_phones = {
"Виктор": "+7 905 600 50 40",
"Юлия": "+7 960 540 43 32",
"Александр": "+7 960 830 72 61"
}
print(team_phones.keys())
print(team_phones.values())
print(team_phones.items())
В консольном терминале появится следующий вывод:
dict_keys(['Виктор', 'Юлия', 'Александр'])
dict_values(['+7 905 600 50 40', '+7 960 540 43 32', '+7 960 830 72 61'])
dict_items([('Виктор', '+7 905 600 50 40'), ('Юлия', '+7 960 540 43 32'), ('Александр', '+7 960 830 72 61')])
Словарь в языке Python — неупорядоченная структура данных вида «ключ — значение», с которой можно можно делать следующие операции:
Таким образом, словарь решает множество проблем, связанных с поиском определенного значения внутри большой структуры данных — любое значение из словаря извлекается с помощью соответствующего ему ключа.