Книга Изучаем Python
Скачать 4.68 Mb.
|
116 Глава 6 • Словари создать словарь для каждого пользователя сайта, как это было сделано в програм- ме user .py на с. 108, и сохранить отдельные словари в списке с именем users . Все словари в списке должны иметь одинаковую структуру, чтобы вы могли перебрать список и выполнить с каждым объектом словаря одни и те же операции. Список в словаре Иногда бывает удобно поместить список в словарь, вместо того чтобы помещать словарь в список. Представьте, как бы вы описали в программе заказанную пиццу. Если ограничиться только списком, сохранить удастся разве что список дополне- ний к пицце. При использовании словаря список дополнений может быть всего лишь одним аспектом описания пиццы. В следующем примере для каждой пиццы сохраняются два вида информации: тип теста и список дополнений. Список дополнений представляет собой значение, связанное с ключом 'toppings' . Чтобы использовать элементы в списке, нужно указать имя словаря и ключ 'toppings' , как и для любого другого значения в сло- варе. Вместо одного значения будет получен список дополнений: pizza.py # Сохранение информации о заказанной пицце. pizza = { 'crust': 'thick', 'toppings': ['mushrooms', 'extra cheese'], } # Описание заказа. print("You ordered a " + pizza['crust'] + "-crust pizza " + "with the following toppings:") for topping in pizza['toppings']: print("\t" + topping) Работа начинается в точке со словаря с информацией о заказанной пицце. С ключом в словаре 'crust' связано строковое значение 'thick' . С другим ключом 'toppings' связано значение-список, в котором хранятся все заказанные допол- нения. В точке выводится описание заказа перед созданием пиццы. Чтобы вы- вести список дополнений, мы используем ключ 'toppings' , а Python берет список дополнений из словаря. Следующее сообщение описывает пиццу, которую мы собираемся создать: You ordered a thick-crust pizza with the following toppings: mushrooms extra cheese Вложение списка в словарь может применяться каждый раз, когда с одним ключом словаря должно быть связано более одного значения. Если бы в предыдущем при- мере с языками программирования ответы сохранялись в списке, один участник опроса мог бы выбрать сразу несколько любимых языков. При переборе словаря значение, связанное с каждым человеком, представляло бы собой список языков Вложение 117 (вместо одного языка.) В цикле for словаря создается другой цикл для перебора списка языков, связанных с каждым участником: favorite_languages.py favorite_languages = { 'jen': ['python', 'ruby'], 'sarah': ['c'], 'edward': ['ruby', 'go'], 'phil': ['python', 'haskell'], } for name, languages in favorite_languages.items(): print("\n" + name.title() + "'s favorite languages are:") for language in languages: print("\t" + language.title()) Вы видите в точке , что значение, связанное с каждым именем, теперь представ- ляет собой список. У некоторых участников только один любимый язык програм- мирования, у других таких языков несколько. При переборе словаря в точке переменная с именем languages используется для хранения каждого значения из словаря, потому что мы знаем, что каждое значение будет представлять собой список. В основном цикле по элементам словаря другой цикл перебирает эле- менты списка любимых языков каждого участника. Теперь каждый участник опроса может указать сколько угодно любимых языков программирования: Jen's favorite languages are: Python Ruby Sarah's favorite languages are: C Phil's favorite languages are: Python Haskell Edward's favorite languages are: Ruby Go Чтобы дополнительно усовершенствовать программу, включите в начало цикла for словаря команду if для проверки того, выбрал ли данный участник более одного языка программирования (проверка основана на значении len(languages) ). Если у участника только один любимый язык, текст сообщения изменяется для един- ственного числа (например, «Sarah’s favorite language is C»). ПРИМЕЧАНИЕ Глубина вложения списков и словарей не должна быть слишком большой . Если вам при- ходится вкладывать элементы на глубину существенно бо́льшую, чем в предыдущих при- мерах, или если вы работаете с чужим кодом со значительной глубиной вложения, скорее всего, у задачи существует более простое решение . 118 Глава 6 • Словари Словарь в словаре Словарь также можно вложить в другой словарь, но в таких случаях код быстро усложняется. Например, если на сайте есть несколько пользователей с уникаль- ными именами, вы можете использовать имена пользователей как ключи в сло- варе. Информация о каждом пользователе при этом хранится в словаре, который используется как значение, связанное с именем. В следующем примере о каждом пользователе хранятся три вида информации: имя, фамилия и место жительства. Чтобы получить доступ к этой информации, переберите имена пользователей и словарь с информацией, связанной с каждым именем: many_users.py users = { 'aeinstein': { 'first': 'albert', 'last': 'einstein', 'location': 'princeton', }, 'mcurie': { 'first': 'marie', 'last': 'curie', 'location': 'paris', }, } for username, user_info in users.items(): print("\nUsername: " + username) full_name = user_info['first'] + " " + user_info['last'] location = user_info['location'] print("\tFull name: " + full_name.title()) print("\tLocation: " + location.title()) В программе определяется словарь с именем users , содержащий два ключа: для пользователей 'aeinstein' и 'mcurie' . Значение, связанное с каждым ключом, представляет собой словарь с именем, фамилией и местом жительства пользова- теля. В процессе перебора словаря users в точке Python сохраняет каждый ключ в переменной username , а словарь, связанный с каждым именем пользователя, со- храняется в переменной user_info . Внутри основного цикла в словаре выводится имя пользователя . В точке начинается работа с внутренним словарем. Переменная user_info , со- держащая словарь с информацией о пользователе, содержит три ключа: 'first' , 'last' и 'location' . Каждый ключ используется для построения аккуратно от- форматированных данных с полным именем и местом жительства пользователя, с последующим выводом сводки известной информации о пользователе : Username: aeinstein Full name: Albert Einstein Location: Princeton Username: mcurie Full name: Marie Curie Location: Paris Итоги 119 Обратите внимание на идентичность структур словарей всех пользователей. Хотя Python этого и не требует, наличие единой структуры упрощает работу с вложен- ными словарями. Если словари разных пользователей будут содержать разные ключи, то код в цикле for заметно усложнится. УПРАЖНЕНИЯ 6-7 . Люди: начните с программы, написанной для упражнения 6-1 (с . 107) . Создайте два новых словаря, представляющих разных людей, и сохраните все три словаря в списке с именем people . Переберите элементы списка людей . В процессе перебора выведите всю имеющуюся информацию о каждом человеке . 6-8 . Домашние животные: создайте несколько словарей, имена которых представляют клички домашних животных . В каждом словаре сохраните информацию о виде животно- го и имени владельца . Сохраните словари в списке с именем pets . Переберите элементы списка . В процессе перебора выведите всю имеющуюся информацию о каждом животном . 6-9 . Любимые места: создайте словарь с именем favorite_places . Придумайте названия трех мест, которые станут ключами словаря, и сохраните для каждого человека от одного до трех любимых мест . Чтобы задача стала более интересной, опросите нескольких друзей и соберите реальные данные для своей программы . Переберите данные в словаре, выведи- те имя каждого человека и его любимые места . 6-10 . Любимые числа: измените программу из упражнения 6-2 (с . 107), чтобы для каждого человека можно было хранить более одного любимого числа . Выведите имя каждого чело- века в списке и его любимые числа . 6-11 . Города: создайте словарь с именем cities . Используйте названия трех городов в каче- стве ключей словаря . Создайте словарь с информацией о каждом городе; включите в него страну, в которой расположен город, примерную численность населения и один примеча- тельный факт, относящийся к этому городу . Ключи словаря каждого города должны на- зываться country, population и fact . Выведите название каждого города и всю сохраненную информацию о нем . 6-12 . Расширение: примеры, с которыми мы работаем, стали достаточно сложными, и в них можно вносить разного рода усовершенствования . Воспользуйтесь одним из примеров этой главы и расширьте его: добавьте новые ключи и значения, измените контекст программы или улучшите форматирование вывода . Итоги В этой главе вы научились определять словари и работать с хранящейся в них информацией. Вы узнали, как обращаться к отдельным элементам словаря и из- менять их, как перебрать всю информацию в словаре. Вы научились перебирать пары «ключ—значение», ключи и значения словаря. Также были рассмотрены воз- можности вложения словарей в список, вложения списков в словари и вложения словарей в другие словари. В следующей главе будут рассмотрены циклы while и получение входных данных от пользователей программ. Эта глава будет особенно интересной, потому что вы наконец-то сможете сделать свои программы интерактивными: они начнут реаги- ровать на действия пользователя. 7 Ввод данных и циклы while Программы, как правило, пишутся для решения задач конечного пользователя. Для этого им обычно нужна некоторая информация, которую должен ввести пользо- ватель. Простой пример: допустим, пользователь хочет узнать, достаточен ли его возраст для голосования. Если вы пишете программу для ответа на этот вопрос, то вам нужно будет узнать возраст пользователя. Программа должна запросить у поль- зователя значение — его возраст; когда у программы появятся данные, она может сравнить их с возрастом, дающим право на голосование, и сообщить результат. В этой главе вы узнаете, как получить пользовательский ввод (то есть входные данные), чтобы программа могла работать с ним. Например, таким вводом может быть отдельное имя или список имен. Для получения данных в программах ис- пользуется функция input() Вы также научитесь продолжать работу программы, пока пользователь вводит новые данные; после получения всех данных программа переходит к работе с полу- ченной информацией. Цикл while в языке Python позволяет выполнять программу, пока некоторое условие остается истинным. Когда вы научитесь работать с пользовательским вводом и управлять продолжи- тельностью выполнения программы, вы сможете создавать полностью интерак- тивные программы. Как работает функция input() Функция input() приостанавливает выполнение программы и ожидает, пока пользователь введет некоторый текст. Получив ввод, Python сохраняет его в пере- менной, чтобы вам было удобнее работать с ним. Например, следующая программа предлагает пользователю ввести текст, а затем выводит сообщение для пользователя: parrot.py message = input("Tell me something, and I will repeat it back to you: ") print(message) Функция input() получает один аргумент: текст подсказки (или инструкции), который выводится на экран, чтобы пользователь понимал, что от него требуется. В данном примере при выполнении первой строки пользователь видит подсказку с предложением ввести любой текст. Программа ожидает, пока пользователь введет Как работает функция input() 121 ответ, и продолжает работу после нажатия Enter . Ответ сохраняется в переменной message , после чего вызов print(message) дублирует введенные данные: Tell me something, and I will repeat it back to you: Hello everyone! Hello everyone! ПРИМЕЧАНИЕ Sublime Text не запускает программы, запрашивающие входные данные у пользователя . Вы можете использовать Sublime Text для создания таких программ, но запускать их придется из терминального окна . См . «Запуск программ Python в терминале», с . 29 . Содержательные подсказки Каждый раз, когда в вашей программе используется функция input() , вы должны включать четкую, понятную подсказку, которая точно сообщит пользователю, какую информацию вы от него хотите получить. Подойдет любое предложение, которое сообщает пользователю, что нужно вводить. Пример: greeter.py name = input("Please enter your name: ") print("Hello, " + name + "!") Добавьте пробел в конце подсказки (после двоеточия в предыдущем примере), чтобы отделить подсказку от данных, вводимых пользователем, и четко показать, где должен вводиться текст. Пример: Please enter your name: Eric Hello, Eric! Иногда подсказка занимает более одной строки. Например, вы можете сообщить поль- зователю, для чего программа запрашивает данные. Текст подсказки можно сохранить в переменной и передать эту переменную функции input() : вы строите длинное при- глашение из нескольких строк, а потом выполняете одну компактную команду input() greeter.py prompt = "If you tell us who you are, we can personalize the messages you see." prompt += "\nWhat is your first name? " name = input(prompt) print("\nHello, " + name + "!") В этом примере продемонстрирован один из способов построения длинных строк. Первая часть длинного сообщения сохраняется в переменной prompt . Затем опера- тор += объединяет текст, хранящийся в prompt , с новым фрагментом текста. Теперь содержимое prompt занимает две строки (вопросительный знак снова от- деляется от ввода пробелом): If you tell us who you are, we can personalize the messages you see. What is your first name? Eric Hello, Eric! 122 Глава 7 • Ввод данных и циклы while Использование int() для получения числового ввода При использовании функции input() Python интерпретирует все данные, введен- ные пользователем, как строку. В следующем сеансе интерпретатора программа запрашивает у пользователя возраст: >>> age = input("How old are you? ") How old are you? 21 >>> age '21' Пользователь вводит число 21, но, когда мы запрашиваем у Python значение age , выводится '21' — представление введенного числа в строковом формате. Кавычки, в которые заключены данные, указывают на то, что Python интерпре- тирует ввод как строку. Но попытка использовать данные как число приведет к ошибке: >>> age = input("How old are you? ") How old are you? 21 >>> age >= 18 Traceback (most recent call last): File " TypeError: unorderable types: str() >= int() Когда вы пытаетесь сравнить введенные данные с числом в точке , Python выдает ошибку, потому что не может сравнить строку с числом: строка '21' , хранящаяся в age , не сравнивается с числовым значением 18; происходит ошибка . Проблему можно решить при помощи функции int() , интерпретирующей строку как числовое значение. Функция int() преобразует строковое представление числа в само число: >>> age = input("How old are you? ") How old are you? 21 >>> age = int(age) >>> age >= 18 True В этом примере введенный текст 21 интерпретируется как строка, но затем он преобразуется в числовое представление вызовом int() в точке . Теперь Python может проверить условие: сравнить переменную age (которая теперь содержит числовое значение 21) с 18. Условие «значение age больше или равно 18» выпол- няется, и результат проверки равен True Как использовать функцию int() в реальной программе? Допустим, программа проверяет рост пользователя и определяет, достаточен ли он для катания на ат- тракционе: rollercoaster.py height = input("How tall are you, in inches? ") height = int(height) Как работает функция input() 123 if height >= 36: print("\nYou're tall enough to ride!") else: print("\nYou'll be able to ride when you're a little older.") Программа может сравнить height с 36, потому что строка height = int(height) преобразует входное значение в число перед проведением сравнения. Если введен- ное число больше или равно 36, программа сообщает пользователю, что он прошел проверку: How tall are you, in inches? 71 You're tall enough to ride! Если пользователь вводит числовые данные, которые используются в вашей про- грамме для вычислений и сравнений, обязательно преобразуйте введенное значение в его числовой эквивалент. Оператор вычисления остатка При работе с числовыми данными может пригодиться оператор вычисления остат- ка ( % ), который делит одно число на другое и возвращает остаток: >>> 4 % 3 1 >>> 5 % 3 2 >>> 6 % 3 0 >>> 7 % 3 1 Оператор % не сообщает частное от целочисленного деления; он возвращает только остаток. Когда одно число нацело делится на другое, остаток равен 0, и оператор % возвра- щает 0. Например, этот факт может использоваться для проверки четности или нечетности числа: even_or_odd.py number = input("Enter a number, and I'll tell you if it's even or odd: ") number = int(number) if number % 2 == 0: print("\nThe number " + str(number) + " is even.") else: print("\nThe number " + str(number) + " is odd.") Четные числа всегда делятся на 2. Следовательно, если остаток от деления на 2 равен 0 ( number % 2 == 0 ), число четное, а если нет — нечетное. Enter a number, and I'll tell you if it's even or odd: 42 The number 42 is even. 124 Глава 7 • Ввод данных и циклы while Ввод данных в Python 2 .7 Если вы работаете с Python 2.7, для запроса данных у пользователя следует ис- пользовать функцию raw_input() . Эта функция интерпретирует весь ввод как строку — точно так же, как функция input() в Python 3. В Python 2.7 также есть функция input() , но эта функция интерпретирует пользо- вательский ввод как код Python и пытается выполнить его. В лучшем случае Python не сможет интерпретировать введенные данные, и вы получите сообщение об ошиб- ке; в худшем случае будет выполнен код, который вы выполнять не собирались. Итак, в Python 2.7 вместо функции input() используется функция raw_input() |