Словари

Проблема

В статье про списки мы организовали хранение рекомендаций следующим образом:

Рекомендация — это строка, наподобие «Упростите код», «Перепишите без if». По мере развития проекта выяснилось, что одного короткого предложения мало. Студенты просто не понимают, что им нужно улучшить. Было решено разделить рекомендацию на две части: короткий заголовок и длинное описание.

С нашими текущими знаниями разделить рекомендацию на заголовок и описание можно следующим образом:

suggestion_titles = []
suggestion_descriptions = []

for i in range(number_of_suggestions):
   suggestion_titles.append(input('Заголовок: '))
   suggestion_descriptions.append(input('Описание: '))

И это вполне приемлемый вариант реализации. Убедитесь, что он работает:

Но дело в том, что рекомендация — ключевая сущность. У неё есть много причин меняться. Сегодня ей нужно описание, а завтра понадобится добавить подсказку. В качестве упражнения, добавьте к каждой рекомендации подсказку с помощью списка suggestion_hints . Используйте для этого код выше.

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

Сейчас мы разберём структуру данных, которая позволит нам связать заголовок, описание и подсказку рекомендации явным образом. Это позволит вернуться к одному-единственному списку.

Создание и чтение

Итак, у нас есть три вида строк: заголовок, описание, подсказка. Они разнородные по содержанию, но связанные по сути: они все описывают рекомендацию.

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

suggestion = {
    'title': 'Вычислите булево значение без if',
    'description': 'Результат любого сравнения: `==`, `<`, `>`, `is` — это всегда True или False. Воспользуйтесь этим, чтобы не писать лишние условия `if`.',
    'hint': 'Короткая запись `return count == 50`',
}

У словаря suggestion есть атрибуты title, description и hint. Доступ к атрибутам можно получить с помощью индексов:

print(suggestion['title'])
print(suggestion['description'])
print(suggestion['hint'])

Итак, перепишем наш пример с использованием словарей:

number_of_suggestions = 4

suggestions = []
for i in range(number_of_suggestions):
    suggestion = {}
    suggestion['title'] = input('Заголовок: ')
    suggestion['description'] = input('Описание: ')
    suggestion['hint'] = input('Подсказка: ')
    suggestions.append(suggestion)


for i in range(number_of_suggestions):
    print(suggestions[i]['title'])
    print(suggestions[i]['description'])
    print(suggestions[i]['hint'])

Теперь список у нас один, а атрибуты связаны явным образом.

Запись и косвенное индексирование

Пример выше использует возможности словарей, которые мы ещё не обсуждали. Следующая строка объявляет пустой словарь:

suggestion = {}

Так как она находится внутри тела цикла, пустой словарь создаётся каждый раз новый.

Запись новых значений в словарь осуществляется так:

suggestion['title'] = input('Заголовок: ')

Здесь title — это название атрибута («ключ»), а input('Заголовок: ’)— значение атрибута.

Чтобы получить из списка словарь, мы указываем конкретный индекс словаря в списке. Затем мы указываем ключ, который хотим получить. Запустите следующий пример для иллюстрации:

Попробуйте в примере выше получить доступ к описанию второй рекомендации в списке с помощью индексов. Этот приём называется косвенным индексированием.

Что дальше

В статье про итерации мы рассказываем, как, имея список или словарь, получить доступ ко всем их элементам.

Альтернативные источники

Если мы не смогли объяснить материал, напишите нам или попробуйте альтернативные источники по теме: