Тип dict: словари
Словарь в Python (тип данных dict) — это неупорядоченная коллекция элементов; каждый элемент словаря состоит из пары
ключ:значение
. Аналогией можно считать толковый словарь, где каждому отдельному слову соответствует его определение.
Словари в Python записываются в фигурных скобках
{}
.- между ключом и значением ставится двоеточие
:
; - в пределах словаря каждый ключ уникален;
- элементы словаря разделяются запятой.
Словарь — это удобно
В программе, получающей данные из онлайн-кинотеатра, данные о фильмах хранились отдельными списками:
Скопировать кодPYTHONmovies = ['Матрица', 'Хакеры', 'Трон', 'Кибер', 'Пятая власть']
movie_ratings = [4.7, 4.3, 3.8, 2.5, 4.1]
Все эти данные можно хранить в одном словаре, сопоставив названия фильмов и их оценки:
Скопировать кодPYTHON# При литеральном объявлении любые коллекции (и словари, в том числе)
# удобно записывать с переносом строк.
movies = {
'Матрица': 4.7,
'Хакеры': 4.3,
'Трон': 3.8,
'Кибер': 2.5,
'Пятая власть': 4.1
}
В этом словаре ключами служат строки
str
, названия фильмов. Ключами могут быть любые неизменяемые объекты.
Скопировать кодPYTHONstatus_dict = {
'on': 1,
0: 'off',
(0, 1): 'выключатель сломан'
}
Литеральное объявление словаря
Литерал для словаря такой же, как и для множества — фигурные скобки
{}
. Через этот литерал можно создавать и пустые словари.Скопировать кодPYTHONempty_dict = {}
print(empty_dict)
# Вывод в терминал: {}
print(type(empty_dict))
# Вывод в терминал: <class 'dict'>
Объявление словаря через функцию dict()
Для создания словаря можно применить функцию
dict()
,
в качестве аргумента ей передаётся список кортежей, каждый из которых
должен состоять из двух элементов; эти кортежи будут преобразованы в
элементы словаря. В каждом элементе словаря ключом будет элемент кортежа с индексом
[0]
(он должен быть объектом неизменяемого типа), а значением для этого ключа будет элемент с индексом [1]
.Скопировать кодPYTHONmovies = [('Матрица', 4.7), ('Трон', 3.8)]
movies_dict = dict(movies)
print(movies_dict)
# Вывод в терминал: {'Матрица': 4.7, 'Трон': 3.8}
Если в каких-то кортежах, переданных в
dict()
, элементы [0]
совпадут — в итоговый словарь попадёт последнее значение для дублирующегося ключа.Выполните код и посмотрите, как
dict()
обработает повторяющиеся ключи:КодPYTHON
4
1
movies = [('Матрица', 4.7), ('Трон', 3.8), ('Хакеры', 4.3), ('Матрица', 4.0)]
2
3
movies_dict = dict(movies)
4
print(movies_dict)
Запустите программу и убедитесь, что результатом будет словарь.
Подставьте вместо названия фильма числовое значение и проверьте что получится.
КодPYTHON
2
1
movies_dict = dict(Матрица = 4.7, Трон = 3.8, Хакеры = 4.3)
2
print(movies_dict)
Есть и другие способы объявить словарь.
Метод dict.fromkeys()
Метод принимает в качестве обязательного аргумента последовательность элементов. Значения элементов будут ключами словаря.
Вторым,
необязательным аргументом можно передать любой объект, который будет
значением для всех ключей словаря. По умолчанию он равен
None
.Скопировать кодPYTHONmovies = dict.fromkeys(['Матрица', 'Хакеры', 'Трон', 'Кибер'])
print(movies)
# Вывод в терминал: {'Матрица': None, 'Хакеры': None, 'Трон': None, 'Кибер': None}
movies = dict.fromkeys(['Матрица', 'Хакеры', 'Трон', 'Кибер'], 4.8)
print(movies)
# Вывод в терминал: {'Матрица': 4.8, 'Хакеры': 4.8, 'Трон': 4.8, 'Кибер': 4.8}
Функция zip()
Функция-упаковщик
zip()
принимает в качестве аргументов итерируемые объекты, а возвращает объект типа zip — это коллекция кортежей. Каждый из кортежей содержит элементы исходных коллекций с одинаковыми индексами.Функция
zip()
может принять на вход любое количество последовательностей; если передать в zip()
три последовательности — каждый кортеж в zip-объекте будет содержать три элемента.Напечатать zip-объект невозможно: содержимое упаковано.
Скопировать кодPYTHONmovie_ratings= [4.7, 5.0, 4.3, 4.0]
movies = ['Матрица', 'Хакеры', 'Трон', 'Кибер']
movies_info = zip(movies, movie_ratings)
print(movies_info)
# Вывод в терминал: <zip object at 0x017D4B48>
# Всё так упаковано, что элементы не видны. Но они есть!
Однако обращаться к элементам zip-объекта можно точно так же, как и к элементам любой другой последовательности.
Объекты типа
zip
— итерируемые. Переберите в цикле элементы объекта movies_info
и напечатайте их.КодPYTHON
7
1
movie_ratings= [4.7, 5.0, 4.3, 4.0]
2
movies = ['Матрица', 'Хакеры', 'Трон', 'Кибер']
3
4
movies_info = zip(movies, movie_ratings)
5
6
for zip in movies_info:
7
print(zip)
Передадим объект типа
zip
в качестве аргумента функции dict()
:Скопировать кодPYTHONmovie_ratings= [4.7, 5.0, 4.3, 4.0]
movies = ['Матрица', 'Хакеры', 'Трон', 'Кибер']
movies_info = zip(movies, movie_ratings)
print(dict(movies_info))
# Вывод в терминал: {'Матрица': 4.7, 'Хакеры': 5.0, 'Трон': 4.3, 'Кибер': 4.0}
Готово! Из двух последовательностей собрали словарь, буквально двумя строками кода.
Преобразование
из zip-объекта в словарь сработает только в том случае, если в zip
упакованы две последовательности. В любом другом случае при попытке
создать словарь из zip-объекта функция
dict()
вернёт ошибку.Скопировать кодPYTHONmovie_ratings= [4.7, 5.0, 4.3, 4.0]
movies = ['Матрица', 'Хакеры', 'Трон', 'Кибер']
review = ['Фильм крут', 'Фильм крут', 'Смотреть можно', 'Смотреть можно']
movies_info = zip(movies, movie_ratings, review)
print(dict(movies_info))
# Вывод в терминал:
Traceback (most recent call last):
File ".../main.py", line 7, in <module>
print(dict(movies_info))
ValueError: dictionary update sequence element 0 has length 3; 2 is required
Хозяйке на заметку: если последовательности, переданные в
zip()
, не совпадают по длине — ничего не сломается. Функция zip()
умная, она самостоятельно отсечёт лишние элементы.Скопировать кодPYTHONmovie_ratings= [4.7, 5.0, 4.3, 4.0]
movies = ['Матрица', 'Хакеры', 'Трон', 'Кибер', 'Сеть']
zipped_movies = zip(movies, movie_ratings)
print(dict(zipped_movies))
# Вывод в терминал: {'Матрица': 4.7, 'Хакеры': 5.0, 'Трон': 4.3, 'Кибер': 4.0}
Создание словаря через dict comprehensions
Словари, как и списки, можно создавать при помощи компактной конструкции dict comprehensions.
Эта
конструкция создаёт словарь на основе значений какой-то исходной
последовательности, пробегаясь по ней циклом, получая её элементы и
создавая ключи и значения элементов словаря.
Скопировать кодPYTHON<имя_словаря> = {
<ключ>:<значение> for <переменная_цикла> in <имя_исходной_последовательности>
}
В этой записи
<ключ>
и <значение>
составляют элемент словаря; они могут быть любыми выражениями, которые создадут этот элемент.Скопировать кодPYTHON# В цикле for перебираем последовательность range(3),
# по очереди передаём значение каждого элемента в переменную num,
# для каждого элемента словаря создаём ключ и значение
new_dict = {'Ключ ' + str(num) : 'Значение ' + str(num) for num in range(3)}
print(new_dict)
# Вывод в терминал:
# {'Ключ 0': 'Значение 0', 'Ключ 1': 'Значение 1', 'Ключ 2': 'Значение 2'}
Например,
если из списка фильмов необходимо создать словарь, в котором ключами
будут названия фильмов, а значениями — их категория, для всех
одинаковая, то можно написать такой код:
Скопировать кодPYTHONmovies = ['Матрица', 'Хакеры', 'Трон']
сategory = 'Фантастика в IT'
movies_info = {movie:сategory for movie in movies}
print(movies_info)
# Вывод в терминал:
#{'Матрица': 'Фантастика в IT', 'Хакеры': 'Фантастика в IT', 'Трон': 'Фантастика в IT'}
Методы словарей
Обращение к элементам словаря
Получить
значение списка или кортежа можно обратившись к нему по индексу, но
словарь — это неупорядоченная коллекция, и обращение по индексу вызовет
исключение.
Скопировать кодPYTHONmovies = {
'Матрица': 4.7,
'Хакеры': 4.3,
'Трон': 3.8,
'Кибер': 2.5,
'Пятая власть': 4.1
}
# Попытка обратиться к элементу словаря по индексу...
print(movies[0])
# ...всё испортит:
# Вывод в терминал: KeyError: 0
Единственный способ получить значения словаря — обратиться к нему по ключу.
Скопировать кодPYTHONmovies = {
'Матрица': 4.7,
'Хакеры': 4.3,
'Трон': 3.8,
'Кибер': 2.5,
'Пятая власть': 4.1
}
# Получение значение элемента словаря с ключем 'Кибер'
print(movies['Кибер'])
# Вывод в терминал: 2.5
Значением
словаря может быть вложенный словарь; это бывает удобно для хранения
структурированной информации. Например все параметры фильма можно
хранить под осмысленными ключами.
Определите, что выведет в терминал эта программа:
Скопировать кодPYTHONmovies = {
'Матрица': {'rating': '4.7', 'review': 'Фильм крут'},
'Хакеры': {'rating': '4.5', 'review': 'Смотреть можно'},
'Трон': {'rating': '3.8', 'review': 'Смотреть можно'},
'Кибер': {'rating': '2.5', 'review': 'Так себе киношечка'},
'Пятая власть': {'rating': '4.1', 'review': 'Смотреть можно'},
}
hackers = movies['Хакеры']
print(hackers['rating'], hackers['review'])
Нет. Программа выведет значения для ключей
'rating'
и 'review'
вложенного словаря, который хранится под ключом 'Хакеры'
: 4.5 Смотреть можно
Нет. Программа выведет значения для ключей
'rating'
и 'review'
вложенного словаря, который хранится под ключом 'Хакеры'
: 4.5 Смотреть можно
Проверка «есть ли ключ в словаре?»
Проверить, есть ли запрашиваемый ключ в словаре, можно через оператор
in
, он работает так же, как и в других коллекциях.Скопировать кодPYTHONmovies = {
'Матрица': {'rating': '4.7', 'review': 'Фильм крут'},
'Хакеры': {'rating': '4.5', 'review': 'Смотреть можно'},
'Трон': {'rating': '3.8', 'review': 'Смотреть можно'},
'Кибер': {'rating': '2.5', 'review': 'Так себе киношечка'},
'Пятая власть': {'rating': '4.1', 'review': 'Смотреть можно'},
}
movie = 'Трон'
# Проверка: есть ли фильм с нужным названием в словаре movies:
if movie in movies:
# Если такой ключ есть - программа выведет сообщение
print("Информация об этом фильме доступна")
else:
# Если ключа с названием фильма нет в словаре, программа
# выведет соответсвующее сообщение
print("Информация о фильме отсутствует!")
Метод get()
Метод
get()
возвращает из словаря значение по ключу. Если запрошенный ключ не найден — вернётся None
или значение, переданное вторым аргументом; это отличает метод dict.get(key)
от обращения к значению по ключу dict[key]
: если запрошенный ключ не найден — dict[key]
вызовет ошибку.Скопировать кодPYTHONmovies = {
'Матрица': {'rating': 4.7, 'review': 'Фильм крут'},
'Хакеры': {'rating': 4.5, 'review': 'Смотреть можно'},
'Трон': {'rating': 3.8, 'review': 'Смотреть можно'},
'Кибер': {'rating': 2.5, 'review': 'Так себе киношечка'},
'Пятая власть': {'rating': 4.1, 'review': 'Смотреть можно'},
}
# Вызов метода get() с одним обязательным параметром
print(movies.get('Хоббит'))
# Вывод в терминал: None
# Вызов метода get() с двумя аргументами
# Второй аргумент - значение, которое вернётся, если ключ в словаре не найден.
print(movies.get('Хатико', 'Такого фильма нет в словаре'))
# Вывод в терминал: Такого фильма нет в словаре
print(movies.get('Трон'))
# Вывод в терминал: {'rating': 3.8, 'review': 'Смотреть можно'}
Добавление нового элемента в словарь
Для добавления элемента в словарь нужно новому ключу словаря присвоить значение.
Скопировать кодPYTHONmovies = {
'Матрица': 4.7,
'Хакеры': 4.3,
'Трон': 3.8,
}
movies['Сеть'] = 4.3
print(movies)
# Вывод в терминал: {'Матрица': 4.7, 'Хакеры': 4.3, 'Трон': 3.8, 'Сеть': 4.3}
Таким же способом можно изменить значение для существующего ключа словаря
Рейтинг фильма «Хакеры» поднялся до максимального значения: 5.0. Задайте новое значение рейтинга для этого фильма в словаре
movies
.КодPYTHON
8
1
movies = {
2
'Матрица': 4.7,
3
'Хакеры': 4.3,
4
'Трон': 3.8,
5
}
6
movies['Хакеры'] = 5.0
7
8
print(movies)
Объединение словарей
Объединить словари можно методом
update()
. Он работает по принципу «добавить все элементы второго словаря в первый»:Скопировать кодPYTHONmovies = {
'Матрица': 4.7,
'Хакеры': 4.3,
'Трон': 3.8,
}
new_movies = {
'Сеть': 4.1,
'23': 4.3,
}
movies.update(new_movies)
print(movies)
# Вывод в терминал: {'Матрица': 4.7, 'Хакеры': 4.3, 'Трон': 3.8, 'Сеть': 4.1, '23': 4.3}
Удаление элемента из словаря
Для удаления элемента словаря применяется оператор
del
.Онлайн-кинотеатр избавляется от непопулярных фильмов: необходимо удалить из словаря все фильмы, рейтинг которых ниже 4.5:
Скопировать кодPYTHONmovies = {
'Матрица': 4.7,
'Хакеры': 5.0,
'Трон': 3.8,
'Кибер': 2.5,
'Пятая власть': 4.1,
}
del movies['Трон']
del movies['Кибер']
del movies['Пятая власть']
print(movies)
# Вывод в терминал: {'Матрица': 4.7, 'Хакеры': 5.0}
Можно не просто удалить элемент словаря, но и вернуть значение удаляемого элемента. Для этого применяется метод
pop()
. Он принимает два аргумента pop(key, default)
:key
— ключ элемента, который нужно удалить из словаря;- необязательный аргумент
default
— значение, которое вернёт метод в случае, если переданный ключ не найден в словаре.
Скопировать кодPYTHONmovies = {
'Матрица': 4.7,
'Хакеры': 4.3,
'Трон': 3.8,
'Кибер': 2.5,
'Пятая власть': 4.1
}
# При попытке получить значение элемента словаря с ключем 'Сеть'
# вернётся значение по умолчанию - 'Фильм не найден'
movie_pop = movies.pop('Сеть', 'Фильм не найден')
print(movie_pop)
# Вывод в терминал: Фильм не найден
movie_pop = movies.pop('Трон')
print(movie_pop)
# Вывод в терминал: 3.8
print(movies)
# Вывод в терминал: {'Матрица': 4.7, 'Хакеры': 4.3, 'Кибер': 2.5, 'Пятая власть': 4.1}
Получение ключей и значений элементов словаря
Метод
keys()
возвращает объект dict_keys
— это последовательность, хранящая ключи словаря. Метод values()
возвращает объект dict_values
: это последовательность, элементами которой будут значения словаря.Скопировать кодPYTHONmovies = {
'Матрица': 4.7,
'Хакеры': 4.3,
'Трон': 3.8,
'Кибер': 2.5,
'Пятая власть': 4.1
}
keys = movies.keys()
print(keys)
# Вывод в терминал: dict_keys(['Матрица', 'Хакеры', 'Трон', 'Кибер', 'Пятая власть'])
values = movies.values()
print(values)
# Вывод в терминал: dict_values([4.7, 4.3, 3.8, 2.5, 4.1])
Перебор словаря
Перебрать все элементы словаря можно циклом
for
. При этой операции в переменную цикла будет передаваться только ключ элемента словаря:Скопировать кодPYTHONmovies = {
'Матрица': 4.7,
'Хакеры': 4.3,
'Трон': 3.8,
'Кибер': 2.5,
'Пятая власть': 4.1
}
for movie_name in movies:
print(movie_name)
# Матрица
# Хакеры
# Трон
# Кибер
# Пятая власть
Выражение
for movie_name in movies
эквивалентно выражению for movie_name in movies.keys()
: по умолчанию перебор словаря выполняется по его ключам.Можно перебрать и значения словаря: для этого надо перебирать не словарь, а объект
dict_values
, полученный из словаря с помощью метода values()
:Скопировать кодPYTHONmovies = {
'Матрица': 4.7,
'Хакеры': 4.3,
'Трон': 3.8,
'Кибер': 2.5,
'Пятая власть': 4.1
}
for movie_rating in movies.values():
print(movie_rating)
# Вывод в терминал:
# 4.7
# 4.3
# 3.8
# 2.5
# 4.1
Чтобы получить из словаря пары
ключ:значение
— применяют метод items()
. Он преобразует словарь в объект dict_items
— это коллекция кортежей, каждый из которых первым элементом содержит ключ, а вторым — значение элемента словаря.Скопировать кодPYTHONmovies = {
'Матрица': 4.7,
'Хакеры': 4.3,
'Трон': 3.8,
'Кибер': 2.5,
}
print(movies.items())
# Вывод в терминал:
# dict_items([('Матрица', 4.7), ('Хакеры', 4.3), ('Трон', 3.8), ('Кибер', 2.5)])
Кортежи из такой коллекции можно распаковать прямо в цикле: для этого нужно после
for
указать имена переменных для распаковки:Скопировать кодPYTHONmovies = {
'Матрица': 4.7,
'Хакеры': 4.3,
'Трон': 3.8,
'Кибер': 2.5,
}
# movies.items() возвращает коллекцию кортежей:
# dict_items([('Матрица', 4.7), ('Хакеры', 4.3), ('Трон', 3.8), ('Кибер', 2.5)])
# При переборе этой коллекции в цикле
# первый элемент каждого кортежа будет передаваться в переменную movie
# а второй - в переменную rating
for movie, rating in movies.items():
print(f'Фильм {movie} получил оценку {rating}')
# Вывод в терминал:
# Фильм Матрица получил оценку 4.7
# Фильм Хакеры получил оценку 4.3
# Фильм Трон получил оценку 3.8
# Фильм Кибер получил оценку 2.5
Очистка и копирование словаря
Чтобы очистить словарь — нужно применить метод
clear()
:Скопировать кодPYTHONmovies = {
'Матрица': 4.7,
'Хакеры': 4.3,
'Трон': 3.8,
'Кибер': 2.5,
}
movies.clear()
print(movies)
# Вывод в терминал: {}
# Кина не будет: фильмов нет!
Копирование словаря
Метод
copy()
создаст независимую копию исходного словаря:Скопировать кодPYTHONmovies = {
'Матрица': 4.7,
'Хакеры': 4.3,
'Трон': 3.8,
'Кибер': 2.5,
}
print(id(movies))
# Вывод в терминал: 1781869204544
movies_copy = movies.copy()
print(id(movies_copy))
# Вывод в терминал: 1781869204608
# А если просто присвоить значение movies новой переменной -
# копия не будет создана:
movies_only_link = movies
print(id(movies_only_link))
# Вывод в терминал: 1781869204544
# У movies и movies_only_link один и тот же id,
# значит, обе переменные ссылаются на один объект; копия словаря не создана.
Резюме
- Ключи должны быть уникальны в пределах словаря: не может быть двух одинаковых ключей в одном словаре;
- Ключ должен быть строкой, числом или кортежем — неизменяемым объектом.
- Значения могут быть какими угодно, ограничений нет.
Онлайн
кинотеатр присылает Антону перечень фильмов, рекомендованных к
просмотру. Помогите Антону выбрать фильмы с высоким рейтингом и добавить
в избранное.
Если рекомендованный фильм имеет рейтинг ниже 4.0 — удалите его из словаря
recommended_movie
. При этом программа должна вывести сообщение Скопировать кодФильм "<название_фильма>" не интересен: "<отзыв_о_фильме>". Фильм удалён из рекомендаций.
Все фильмы с рейтингом выше 4.0 программа должна добавить в словарь с избранными фильмами
favorites_movie
и вывести сообщение Скопировать кодУ фильма "<название_фильма>" хороший отзыв: "<отзыв_о_фильме>". Фильм добавлен в избранное.
Напечатайте получившуюся коллекцию избранных фильмов.
КодPYTHON
26
1
favorites_movie = {}
2
3
recommended_movie = {
4
'Хенкок': {'rating': 4.5, 'review': 'Смотреть можно'},
5
'Матрица': {'rating': 4.7, 'review': 'Фильм крут'},
6
'Кибер': {'rating': 2.5, 'review': 'Так себе киношечка'},
7
'Трон': {'rating': 3.8, 'review': 'Так себе киношечка'},
8
'Мстители': {'rating': 4.7, 'review': 'Фильм крут'},
9
'Хакеры': {'rating': 4.5, 'review': 'Смотреть можно'}
10
}
11
low_rating = {}
12
13
for k, j in recommended_movie.items():
14
if j['rating'] < 4.0:
15
print(f'Фильм {k} не интересен: "{j["review"]}". Фильм удалён из рекомендаций.')
16
low_rating[k] = j
17
else:
18
favorites_movie[k] = j
19
print(f'У фильма "{k}" хороший отзыв: "{j["review"]}". Фильм добавлен в избранное.')
20
21
22
for k in low_rating.keys():
23
if k in recommended_movie:
24
del recommended_movie[k]
25
26
print(favorites_movie)