Перейти к содержанию

Словари

Списки — удобный и самый популярный способ сохранить большое количество данных в одной переменной. Списки индексируют все хранящиеся в них элементы. Первый элемент, как мы помним, лежит по индексу 0, второй — по индексу 1 и т. д. Такой способ хранения позволяет быстро обращаться к элементу списка, зная его индекс.

actors = ['Джонни Депп', 'Эмма Уотсон', 'Билли Пайпер']
print(actors[1])

Представим, что мы делаем свою онлайн-энциклопедию об актерах мирового кино (наподобие Википедии). Для каждого актера нужно сохранить текст статьи о нем. Ее название — строка, состоящая из фамилии и имени актера. Как правильно хранить такие данные?

Можно создать список кортежей. Каждый кортеж будет состоять из двух строк — названия и текста статьи.

actors = [
    (
        'Джонни Депп',
        'Джон Кристофер Депп Второй родился 9 июня 1963 года в '
        + 'Овенсборо, Кентукки...'
    ),
    (
        'Сильвестр Сталлоне',
        'Сильвестр Гарденцио Сталлоне родился в Нью-Йорке. Его отец, '
        + ' парикмахер Фрэнк Сталлоне — иммигрант из Сицилии...'
    ),
    (
        'Эмма Уотсон',
        'Эмма Шарлотта Дуерр Уотсон родилась в семье английских '
        + 'адвокатов. В пять лет переехала вместе с семьей из '
        + 'Парижа в Англию...'
    ),
    # ...
]

Со временем количество статей значительно вырастет. Чтобы найти нужную статью по названию, нам придется написать цикл for, который пройдет по всем элементам списка actors и найдет в нем кортеж, первый элемент которого равен искомому названию. В приведенном выше примере, чтобы найти статью об Эмме Уотсон, нам придется в цикле пройти мимо Джонни Деппа и Сильвестра Сталлоне. Угадать заранее, что статья об Эмме Уотсон лежит после них, не получится.

Корень этой проблемы в том, что списки индексируются целыми числами. Мы же хотим находить информацию не по числу, а по строке — названию статьи. Было бы здорово, если бы индексами могли быть не числа, а строки. В списках это невозможно, однако возможно в словарях!

Словарь (в Python он называется dict) — тип данных, позволяющий, как и список, хранить много данных. В отличие от списка, в словаре для каждого элемента можно самому определить «индекс», по которому он будет доступен. Этот индекс называется ключом.

Создание словаря

Вот пример создания словаря для энциклопедии об актерах мирового кино:

1
2
3
4
5
6
actors = {
    'Джонни Депп': 'Джон Кристофер Депп Второй родился 9 июня 1963 года в Овенсборо, Кентукки...',
    'Сильвестр Сталлоне': 'Сильвестр Гарденцио Сталлоне родился в Нью-Йорке. Его отец, парикмахер Фрэнк Сталлоне — иммигрант из Сицилии...',
    'Эмма Уотсон': 'Эмма Шарлотта Дуерр Уотсон родилась в семье английских адвокатов. В пять лет переехала вместе с семьей из Парижа в Англию...',
    # ...
}

Элементы словаря перечисляются в фигурных скобках (как и элементы множества!) и разделяются запятой. До двоеточия указывается ключ, а после двоеточия — значение, доступное в словаре по этому ключу.

Пустой словарь можно создать двумя способами:

1
2
3
d = dict()
# или так:
d = {}

!!! note "Важно Вспомните, что создать пустое множество можно, только используя функцию set(). Теперь понятно, почему это так — пустые фигурные скобки зарезервированы для создания словаря.

Обращение к элементу словаря

После инициализации словаря мы можем быстро получать статью про конкретного актера:

print(actors['Эмма Уотсон'])

Обращение к элементу словаря выглядит как обращение к элементу списка, только вместо целочисленного индекса используется ключ. В качестве ключа можно указать выражение: Python вычислит его значение, прежде чем обратится к искомому элементу.

1
2
3
first_name = 'Сильвестр'
last_name = 'Сталлоне'
print(actors[first_name + ' ' + last_name])

KeyError

Если обратиться к несуществующему ключу, Python выдаст ошибку KeyError:

print(actors['Несуществующий ключ'])
# KeyError: 'Несуществующий ключ'

Добавление и удаление элементов

Важная особенность словаря — его динамичность. Мы можем добавлять новые элементы, изменять их или удалять. Изменяются элементы точно так же, как в списках, только вместо целочисленного индекса в квадратных скобках указывается ключ:

actors['Эмма Уотсон'] = 'Новый текст статьи об Эмме Уотсон'

Также в словари можно добавлять новые элементы и удалять существующие.

Добавление синтаксически выглядит так же, как и изменение:

actors['Брэд Питт'] = 'Уильям Брэдли Питт, более известный как Брэд Питт — американский актёр и продюсер. Лауреат премии «Золотой глобус» за 1995 год...'

Для удаления можно использовать инструкцию del (как и в списках):

del actors['Джонни Депп']
print(actors['Джонни Депп'])  # KeyError: 'Джонни Депп'

Удалять элемент можно и по-другому:

actors.pop('Джонни Депп')

Единственное отличие этого способа от вызова del — он возвращает удаленное значение. Можно написать так:

deleted_value = actors.pop('Джонни Депп')

В переменную deleted_value положится значение, которое хранилось в словаре по ключу Джонни Депп. В остальном этот способ идентичен оператору del. В частности, если ключа Джонни Депп в словаре нет, возникнет ошибка KeyError.

Чтобы ошибка не появлялась, этому методу можно передать второй аргумент. Он будет возвращен, если указанного ключа в словаре нет. Это позволяет реализовать безопасное удаление элемента из словаря:

deleted_value = actors.pop('Джонни Депп', None)

Если ключа Джонни Депп в словаре нет, в deleted_value попадет None.

Проверка наличия элемента в словаре

Оператор in позволяет проверить, есть ли ключ в словаре:

if 'Джонни Депп' in actors:
    print('У нас есть статья про Джонни Деппа')

Проверить, что ключа нет, можно с помощью аналогичного оператора not in:

if 'Сергей Безруков' not in actors:
    print('У нас нет статьи о Сергее Безрукове')

!!! tip "Подсказка Оператор in для словарей проверяет наличие ключа, а не значения.

Методы словарей

get

Метод get позволяет получить значение по ключу безопасно — без риска KeyError. Если ключ отсутствует, возвращается None или указанное значение по умолчанию:

1
2
3
4
5
article = actors.get('Джонни Депп')
# Если ключа нет — вернёт None

article = actors.get('Джонни Депп', 'Статья о Джонни Деппа не найдена')
# Если ключа нет — вернёт строку 'Статья о Джонни Деппа не найдена'

keys, values

Методы keys() и values() возвращают все ключи и все значения словаря соответственно. Их удобно преобразовывать в список:

actors_names = list(actors.keys())    # список всех ключей
all_articles = list(actors.values())  # список всех значений

items

Метод items() возвращает пары (ключ, значение) — это удобно для перебора словаря в цикле:

for key, val in d.items():
    pass  # обрабатываем каждую пару
for actor_name, article in actors.items():
    print(actor_name, article)

!!! info "Порядок элементов Начиная с Python 3.7, словари сохраняют порядок добавления элементов. При переборе через items() элементы будут выводиться в том порядке, в котором они были добавлены.


Задачи

Задача 1

Считайте слово и выведите количество вхождений каждой буквы в формате буква: количество, по одной паре на строку, в порядке первого появления буквы в слове.

Тест 1:

Ввод:

банан
Вывод:
б: 1
а: 2
н: 2


Задача 2

Считайте n строк вида имя оценка. Выведите имена и их оценки через :, каждую пару на новой строке.

Тест 1:

Ввод:

3
Аня 5
Боря 4
Вася 3
Вывод:
Аня: 5
Боря: 4
Вася: 3


Задача 3

Считайте n строк вида слово перевод. Затем считайте слово для перевода. Если слово есть в словаре — выведите перевод. Иначе выведите Слово не найдено.

Тест 1:

Ввод:

3
кот cat
дом house
рыба fish
кот
Вывод:
cat

Тест 2:

Ввод:

3
кот cat
дом house
рыба fish
птица
Вывод:
Слово не найдено


Задача 4

Считайте строку. Выведите наиболее часто встречающийся символ (не считая пробелов). Если таких символов несколько — выведите тот, который встречается первым.

Тест 1:

Ввод:

молоко вкусное
Вывод:
о

Тест 2:

Ввод:

абба
Вывод:
а


Задача 5

Считайте n строк вида товар цена. Затем считайте название товара. Выведите его цену. Если товар не найден — выведите Товар не найден.

Тест 1:

Ввод:

4
хлеб 30
молоко 75
масло 120
сыр 200
молоко
Вывод:
75

Тест 2:

Ввод:

4
хлеб 30
молоко 75
масло 120
сыр 200
яйца
Вывод:
Товар не найден


Задача 6

Считайте n строк вида имя оценка. Имена могут повторяться — тогда нужно суммировать оценки. Выведите все имена и суммы оценок в порядке первого появления имени.

Тест 1:

Ввод:

5
Аня 5
Боря 4
Аня 3
Вася 5
Боря 2
Вывод:
Аня: 8
Боря: 6
Вася: 5

Тест 2:

Ввод:

3
Лена 4
Лена 4
Лена 2
Вывод:
Лена: 10


Задача 7

Считайте два списка слов (каждый до пустой строки). Выведите слова, которые есть в первом списке, но отсутствуют во втором, в порядке их появления в первом списке.

Тест 1:

Ввод:

питон
кот
собака

кот
птица
питон
Вывод:
собака

Тест 2:

Ввод:

яблоко
груша
слива

манго
груша
Вывод:
яблоко
слива


Задача 8

Считайте строку. Подсчитайте, сколько раз встречается каждое слово. Выведите все слова и их количество в порядке первого появления, в формате слово: количество. Регистр не учитывается (приводите слова к нижнему регистру).

Тест 1:

Ввод:

кот и кот и собака и кот
Вывод:
кот: 3
и: 3
собака: 1

Тест 2:

Ввод:

Питон питон ПИТОН
Вывод:
питон: 3


Задача 9

Считайте n строк — оценки учеников в формате имя оценка. Выведите имя ученика с наибольшей оценкой. Если таких несколько — выведите того, чьё имя встречается первым.

Тест 1:

Ввод:

4
Аня 5
Боря 3
Вася 5
Гоша 4
Вывод:
Аня

Тест 2:

Ввод:

3
Лена 4
Маша 5
Коля 3
Вывод:
Маша


Задача 10

Считайте n строк, каждая содержит два слова через пробел — оригинал и перевод. Затем считайте текст (одну строку). Замените каждое слово из текста его переводом, если оно есть в словаре, и выведите результат. Слова, которых нет в словаре, оставьте без изменений.

Тест 1:

Ввод:

3
кот cat
дом house
я I
я люблю кот и дом
Вывод:
I люблю cat и house

Тест 2:

Ввод:

2
привет hello
мир world
привет мир питон
Вывод:
hello world питон