Тип 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.07
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] = j17
else:18
favorites_movie[k] = j19
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)