Итоги
В этой главе вы научились писать условия, результатом которых всегда является логическое значение (True или False.) Вы научились писать простые команды if, цепочки if-else и цепочки if-elif-else. Вы начали использовать эти структуры для выявления конкретных условий, которые необходимо проверить, и проверки этих условий в ваших программах. Вы узнали, как обеспечить специальную обработку некоторых элементов в списке с сохранением эффективности циклов for. Также мы вернулись к стилевым рекомендациям Python, с которыми более сложные программы становятся относительно простыми для чтения и понимания.
В главе 6 рассматриваются словари Python. Словарь отчасти напоминает список, но он позволяет связывать разные виды информации. Вы научитесь создавать словари, перебирать их элементы, использовать их в сочетании со списками и командами if. Словари помогут вам моделировать еще более широкий спектр реальных ситуаций.
6. Словари
В этой главе речь пойдет о словарях — структурах данных, предназначенных для объединения взаимосвязанной информации. Вы узнаете, как получить доступ к информации, хранящейся в словаре, и как изменить эту информацию. Так как объем данных в словаре практически безграничен, мы рассмотрим средства перебора данных в словарях. Кроме того, вы научитесь использовать вложенные словари в списках, вложенные списки в словарях и даже словари в других словарях.
Операции со словарями позволяют моделировать всевозможные реальные объекты с большей точностью. Вы узнаете, как создать словарь, описывающий человека, и сохранить в нем сколько угодно информации об этом человеке. В словаре может храниться имя, возраст, место жительства, профессия и любые другие атрибуты. Вы узнаете, как сохранить любые два вида информации, способные образовать пары: список слов и их значений, список имен людей и их любимых чисел, список гор и их высот и т.д.
Простой словарь
Возьмем игру с инопланетными пришельцами, которые имеют разные цвета и приносят разное количество очков игроку. В следующем простом словаре хранится информация об одном конкретном пришельце:
alien.py
alien_0 = {'color': 'green', 'points': 5}
print(alien_0['color'])
print(alien_0['points'])
В словаре alien_0 хранятся два атрибута: цвет (color) и количество очков (points). Следующие две команды print читают эту информацию из словаря и выводят ее на экран:
green
5
Работа со словарями, как и большинство других новых концепций, требует определенного опыта. Стоит вам немного поработать со словарями, и вы увидите, как эффективно они работают при моделировании реальных ситуаций.
Работа со словарями
Словарь в языке Python представляет собой совокупность пар «ключ—значение». Каждый ключ связывается с некоторым значением, и программа может получить значение, связанное с заданным ключом. Значением может быть число, строка, список и даже другой словарь. Собственно, любой объект, создаваемый в программе Python, может стать значением в словаре.
В Python словарь заключается в фигурные скобки {}, в которых приводится последовательность пар «ключ—значение», как в предыдущем примере:
alien_0 = {'color': 'green', 'points': 5}
Пара «ключ—значение» представляет собой данные, связанные друг с другом. Если вы укажете ключ, то Python вернет значение, связанное с этим ключом. Ключ отделяется от значения двоеточием, а отдельные пары разделяются запятыми. В словаре может храниться любое количество пар «ключ—значение».
Простейший словарь содержит ровно одну пару «ключ—значение», как в следующей измененной версии словаря alien_0:
alien_0 = {'color': 'green'}
В этом словаре хранится ровно один фрагмент информации о пришельце alien_0, а именно — его цвет. Строка 'color' является ключом в словаре; с этим ключом связано значение 'green'.
Обращение к значениям в словаре
Чтобы получить значение, связанное с ключом, укажите имя словаря, а затем ключ в квадратных скобках:
alien_0 = {'color': 'green'}
print(alien_0['color'])
Эта конструкция возвращает значение, связанное с ключом 'color', из словаря alien_0:
green
Количество пар «ключ—значение» в словаре не ограничено. Например, вот как выглядит исходный словарь alien_0 с двумя парами «ключ—значение»:
alien_0 = {'color': 'green', 'points': 5}
Теперь программа может получить значение, связанное с любым из ключей в alien_0: color или points. Если игрок сбивает корабль пришельца, для получения заработанных им очков может использоваться код следующего вида:
alien_0 = {'color': 'green', 'points': 5}
(1) new_points = alien_0['points']
(2)print("You just earned " + str(new_points) + " points!")
После того как словарь будет определен, код (1) извлекает значение, связанное с ключом 'points', из словаря. Затем это значение сохраняется в переменной new_points. Строка (2) преобразует целое значение в строку и выводит сообщение с количеством заработанных очков:
You just earned 5 points!
Если этот код будет выполняться каждый раз, когда игрок сбивает очередного пришельца, программа будет получать правильное количество очков.
Добавление новых пар «ключ—значение»
Словари относятся к динамическим структурам данных: в словарь можно в любой момент добавлять новые пары «ключ—значение». Для этого указывается имя словаря, за которым в квадратных скобках следует новый ключ с новым значением.
Добавим в словарь alien_0 еще два атрибута: координаты x и y для вывода изображения пришельца в определенной позиции экрана. Допустим, пришелец должен отображаться у левого края экрана, в 25 пикселах от верхнего края. Так как система экранных координат обычно располагается в левом верхнем углу, для размещения пришельца у левого края координата x должна быть равна 0, а координата y — 25:
alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
(1) alien_0['x_position'] = 0
(2)alien_0['y_position'] = 25
print(alien_0)
Программа начинается с определения того же словаря, с которым мы уже работали ранее. После этого выводится «снимок» текущего состояния словаря. В точке (1) в словарь добавляется новая пара «ключ—значение»: ключ 'x_position' и значение 0. То же самое делается для ключа 'y_position' в точке (2). При выводе измененного словаря мы видим две дополнительные пары «ключ—значение»:
{'color': 'green', 'points': 5}
{'color': 'green', 'points': 5, 'y_position': 25, 'x_position': 0}
Окончательная версия словаря содержит четыре пары «ключ—значение». Первые две определяют цвет и количество очков, а другие две — координаты. Обратите внимание: порядок пар «ключ—значение» не соответствует порядку их добавления. Python не интересует, в каком порядке добавлялись пары; важна лишь связь между каждым ключом и его значением.
Создание пустого словаря
В некоторых ситуациях бывает удобно (или даже необходимо) начать с пустого словаря, а затем добавлять в него новые элементы. Чтобы начать заполнение пустого словаря, определите словарь с пустой парой фигурных скобок, а затем добавляйте новые пары «ключ—значение» (каждая пара в отдельной строке). Например, вот как строится словарь alien_0:
alien_0 = {}
alien_0['color'] = 'green'
alien_0['points'] = 5
print(alien_0)
Программа определяет пустой словарь alien_0, после чего добавляет в него значения для цвета и количества очков. В результате создается словарь, который использовался в предыдущих примерах:
{'color': 'green', 'points': 5}
Обычно пустые словари используются при хранении данных, введенных пользователем, или при написании кода, автоматически генерирующего большое количество пар «ключ—значение».
Изменение значений в словаре
Чтобы изменить значение в словаре, укажите имя словаря с ключом в квадратных скобках, а затем новое значение, которое должно быть связано с этим ключом. Допустим, в процессе игры цвет пришельца меняется с зеленого на желтый:
alien_0 = {'color': 'green'}
print("The alien is " + alien_0['color'] + ".")
alien_0['color'] = 'yellow'
print("The alien is now " + alien_0['color'] + ".")
Сначала определяется словарь alien_0, который содержит только цвет пришельца; затем значение, связанное с ключом 'color', меняется на 'yellow'. Из выходных данных видно, что цвет пришельца действительно сменился с зеленого на желтый:
The alien is green.
The alien is now yellow.
Рассмотрим более интересный пример: отслеживание позиции пришельца, который может двигаться с разной скоростью. Мы сохраним значение, представляющее текущую скорость пришельца, и используем его для определения величины горизонтального смещения:
alien_0 = {'x_position': 0, 'y_position': 25, 'speed': 'medium'}
print("Original x-position: " + str(alien_0['x_position']))
# Пришелец перемещается вправо.
# Вычисляем величину смещения на основании текущей скорости.
(1) if alien_0['speed'] == 'slow':
. .x_increment = 1
elif alien_0['speed'] == 'medium':
. .x_increment = 2
else:
. .# Пришелец двигается быстро.
. .x_increment = 3
# Новая позиция равна сумме старой позиции и приращения.
(2)alien_0['x_position'] = alien_0['x_position'] + x_increment
print("New x-position: " + str(alien_0['x_position']))
Сначала определяется словарь с исходной позицией (координаты x и y) и скоростью 'medium'. Значения цвета и количества очков для простоты опущены, но с ними этот пример работал бы точно так же. Также выводится исходное значение x_position.
В точке (2) цепочка if-elif-else определяет, на какое расстояние пришелец должен переместиться вправо; полученное значение сохраняется в переменной x_increment. Если пришелец двигается медленно ('slow'), то он перемещается на одну единицу вправо; при средней скорости ('medium') он перемещается на две единицы вправо; наконец, при высокой скорости ('fast') он перемещается на три единицы вправо. Вычисленное смещение прибавляется к значению x_position в (2), а результат сохраняется в словаре с ключом x_position.
Для пришельца со средней скоростью позиция смещается на две единицы:
Original x-position: 0
New x-position: 2
Получается, что изменение одного значения в словаре изменяет все поведение пришельца. Например, чтобы превратить пришельца со средней скоростью в быстрого, добавьте следующую строку:
alien_0['speed'] = fast
При следующем выполнении кода блок if-elif-else присвоит x_increment большее значение.
Удаление пар «ключ—значение»
Когда информация, хранящаяся в словаре, перестает быть ненужной, пару «ключ—значение» можно полностью удалить при помощи команды del. При вызове достаточно передать имя словаря и удаляемый ключ.
Например, в следующем примере из словаря alien_0 удаляется ключ 'points' вместе со значением:
alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
(1) del alien_0['points']
print(alien_0)
Строка (1) приказывает Python удалить ключ 'points' из словаря alien_0, а также удалить значение, связанное с этим ключом. Из вывода видно, что ключ 'points' и его значение 5 исчезли из словаря, но остальные данные остались без изменений:
{'color': 'green', 'points': 5}
{'color': 'green'}
примечание
Учтите, что удаление пары «ключ—значение» отменить уже не удастся.
Словарь с однотипными объектами
В предыдущем примере в словаре сохранялась разнообразная информация об одном объекте (пришельце из компьютерной игры). Словарь также может использоваться для хранения одного вида информации о многих объектах. Допустим, вы хотите провести опрос среди коллег и узнать их любимый язык программирования. Результаты простого опроса удобно сохранить в словаре:
favorite_languages = {
. .'jen': 'python',
. .'sarah': 'c',
. .'edward': 'ruby',
. .'phil': 'python',
. .}
Пары в словаре в этой записи разбиты по строкам. Ключами являются имена участников опроса, а значениями — выбранные ими языки. Если вы знаете, что для определения словаря потребуется более одной строки, нажмите клавишу Enter после ввода открывающей фигурной скобки. Снабдите следующую строку отступом на один уровень (четыре пробела) и запишите первую пару «ключ—значение», поставив за ней запятую. После этого при нажатии Enter ваш текстовый редактор будет автоматически снабжать все последующие пары таким же отступом, как у первой.
Завершив определение словаря, добавьте закрывающую фигурную скобку в новой строке после последней пары «ключ—значение» и снабдите ее отступом на один уровень, чтобы она была выровнена по ключам. За последней парой также рекомендуется включить запятую, чтобы при необходимости все было готово к добавлению новой пары «ключ—значение» в следующей строке.
примечание
В большинстве редакторов предусмотрены функции, упрощающие форматирование расширенных списков и словарей в описанном стиле. Также существуют другие распространенные способы форматирования длинных словарей — вы можете столкнуться с ними в вашем редакторе или в другом источнике.
Для заданного имени участника опроса этот словарь позволяет легко определить его любимый язык:
favorite_languages.py
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
(1) print("Sarah's favorite language is " +
(2) . .favorite_languages['sarah'].title() +
(3) . .".")
Чтобы узнать, какой язык выбран пользователем с именем Sarah, мы запрашиваем следующее значение:
favorite_languages['sarah']
Этот синтаксис используется в команде вывода (1) , а результат содержит значение, связанное с ключом:
Sarah's favorite language is C.
Этот пример также показывает, как разбить длинную команду print на несколько строк. Слово print короче большинства имен словарей, поэтому есть смысл включить первую часть выводимого текста сразу же за открывающей круглой скобкой (1) . Выберите точку, в которой будет разбиваться вывод, и добавьте оператор конкатенации (+) в конец первой строки (2). Нажмите Enter, а затем клавишу Tab для выравнивания всех последующих строк на один уровень отступа под командой print. Завершив построение вывода, поставьте закрывающую круглую скобку в последней строке блока print (3).
Упражнения
6-1. Человек: используйте словарь для сохранения информации об известном вам человеке. Сохраните имя, фамилию, возраст и город, в котором живет этот человек. Словарь должен содержать ключи с такими именами, как first_name, last_name, age и city. Выведите каждый фрагмент информации, хранящийся в словаре.
6-2. Любимые числа: используйте словарь для хранения любимых чисел. Возьмите пять имен и используйте их как ключи словаря. Придумайте любимое число для каждого человека и сохраните его как значение в словаре. Выведите имя каждого человека и его любимое число. Чтобы задача стала более интересной, опросите нескольких друзей и соберите реальные данные для своей программы.
6-3. Глоссарий: словари Python могут использоваться для моделирования «настоящего» словаря (чтобы не создавать путаницы, назовем его «глоссарием»).
• Вспомните пять терминов из области программирования, которые вы узнали в предыдущих главах. Используйте эти слова как ключи глоссария, а их определения — как значения.
• Выведите каждое слово и его определение в аккуратно отформатированном виде. Например, вы можете вывести слово, затем двоеточие и определение; или же слово в одной строке, а его определение — с отступом в следующей строке. Используйте символ новой строки (\n) для вставки пустых строк между парами «слово-определение» в выходных данных.