Изучаем Python — страница 19 из 61


До настоящего момента мы работали только с одним фрагментом информации, полученной от пользователя. Мы получали ввод пользователя, а затем выводили ответ на него. При следующем проходе цикла while программа получала новое входное значение и реагировала на него. Но, чтобы работать с несколькими фрагментами информации, необходимо использовать в циклах while списки и словари.

Цикл for хорошо подходит для перебора списков, но, скорее всего, список не должен изменяться в цикле, потому что у Python возникнут проблемы с отслеживанием элементов. Чтобы изменять список в процессе обработки, используйте цикл while. Использование циклов while со списками и словарями позволяет собирать, хранить и упорядочивать большие объемы данных для последующего анализа и обработки.

Возьмем список недавно зарегистрированных, но еще не проверенных пользователей сайта. Как переместить пользователей после проверки в отдельный список проверенных пользователей? Одно из возможных решений: используем цикл while для извлечения пользователей из списка непроверенных, проверяем их и включаем в отдельный список проверенных пользователей. Код может выглядеть так:

confirmed_users.py

# Начинаем с двух списков: пользователей для проверки

# и пустого списка для хранения проверенных пользователей.

(1) unconfirmed_users = ['alice', 'brian', 'candace']

confirmed_users = []


# Проверяем каждого пользователя, пока остаются непроверенные

# пользователи. Каждый пользователь, прошедший проверку,

# перемещается в список проверенных.

(2)while unconfirmed_users:

(3) . .current_user = unconfirmed_users.pop()

. .

. .print("Verifying user: " + current_user.title())

(4) . .confirmed_users.append(current_user)


# Вывод всех проверенных пользователей.

print("\nThe following users have been confirmed:")

for confirmed_user in confirmed_users:

. .print(confirmed_user.title())

Работа программы начинается с двух списков: непроверенных пользователей (1) и пустого списка для проверенных пользователей. Цикл while в точке (2) выполняется, пока в списке unconfirmed_users остаются элементы. Внутри этого списка функция pop() в точке (3) извлекает очередного непроверенного пользователя с конца списка unconfirmed_users. В данном примере список unconfirmed_users завершается пользователем Candace; это имя первым извлекается из списка, сохраняется в current_user и добавляется в список confirmed_users в точке (4). Далее следуют пользователи Brian и Alice.

Программа моделирует проверку каждого пользователя выводом сообщения, после чего переносит пользователя в список проверенных. По мере сокращения списка непроверенных пользователей список проверенных пользователей растет. Когда в списке непроверенных пользователей не остается ни одного элемента, цикл останавливается, и выводится список проверенных пользователей:

Verifying user: Candace

Verifying user: Brian

Verifying user: Alice


The following users have been confirmed:

Candace

Brian

Alice

Удаление всех вхождений конкретного значения из списка


В главе 3 функция remove() использовалась для удаления конкретного значения из списка. Функция remove() работала, потому что интересующее нас значение встречалось в списке только один раз. Но что если вы захотите удалить все вхождения значения из списка?

Допустим, имеется список pets, в котором значение 'cat' встречается многократно. Чтобы удалить все экземпляры этого значения, можно выполнять цикл while до тех пор, пока в списке не останется ни одного экземпляра 'cat':

pets.py

pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']

print(pets)


while 'cat' in pets:

. .pets.remove('cat')

. .

print(pets)

Программа начинает со списка, содержащего множественные экземпляры 'cat'. После вывода списка Python входит в цикл while, потому что значение 'cat' присутствует в списке хотя бы в одном экземпляре. После входа цикл Python удаляет первое вхождение 'cat', возвращается к строке while, а затем обнаруживает, что экземпляры 'cat' все еще присутствуют в списке, и проходит цикл заново. Вхождения 'cat' удаляются до тех пор, пока не окажется, что в списке значений 'cat' не осталось; в этот момент Python завершает цикл и выводит список заново:

['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']

['dog', 'dog', 'goldfish', 'rabbit']

Заполнение словаря данными, введенными пользователем


При каждом проходе цикла while ваша программа может запрашивать любое необходимое количество данных. Напишем программу, которая при каждом проходе цикла запрашивает имя участника и его ответ. Собранные данные будут сохраняться в словаре, потому что каждый ответ должен быть связан с конкретным пользователем:

mountain_poll.py

responses = {}


# Установка флага продолжения опроса.

polling_active = True


while polling_active:

. .# Запрос имени и ответа пользователя.

(1) . .name = input("\nWhat is your name? ")

. .response = input("Which mountain would you like to climb someday? ")

. .

. .# Ответ сохраняется в словаре:

(2) . .responses[name] = response

. .

. .# Проверка продолжения опроса.

(3) . .repeat = input("Would you like to let another person respond? (yes/ no) ")

. .if repeat == 'no':

. . . .polling_active = False

. . . .

# Опрос завершен, вывести результаты.

print("\n--- Poll Results ---")

(4)for name, response in responses.items():

. .print(name + " would like to climb " + response + ".")

Сначала программа определяет пустой словарь (responses) и устанавливает флаг (polling_active), показывающий, что опрос продолжается. Пока polling_active содержит True, Python будет выполнять код в цикле while.

В цикле пользователю предлагается ввести имя и название горы, на которую ему хотелось бы подняться (1) . Эта информация сохраняется в словаре responses в строке (2), после чего программа спрашивает у пользователя, нужно ли продолжать опрос (3). Если пользователь отвечает положительно, то программа снова входит в цикл while. Если же ответ отрицателен, флаг polling_active переходит в состояние False, цикл while перестает выполняться, и завершающий блок кода (4) выводит результаты опроса.

Если вы запустите эту программу и введете пару ответов, результат будет выглядеть примерно так:

What is your name? Eric

Which mountain would you like to climb someday? Denali

Would you like to let another person respond? (yes/ no) yes


What is your name? Lynn

Which mountain would you like to climb someday? Devil's Thumb

Would you like to let another person respond? (yes/ no) no


--- Poll Results ---

Lynn would like to climb Devil's Thumb.

Eric would like to climb Denali.

Упражнения

7-8. Сэндвичи: создайте список с именем sandwich_orders, заполните его названиями различных видов сэндвичей. Создайте пустой список с именем finished_sandwiches. В цикле переберите элементы первого списка и выведите сообщение для каждого элемента (например, «I made your tuna sandwich»). После этого каждый сэндвич из первого списка перемещается в список finished_sandwiches. После того как все элементы первого списка будут обработаны, выведите сообщение с перечислением всех изготовленных сэндвичей.

7-9. Без пастрами: используя список sandwich_orders из упражнения 7-8, проследите за тем, чтобы значение ‘pastrami’ встречалось в списке как минимум три раза. Добавьте в начало программы код для вывода сообщения о том, что пастрами больше нет, и напишите цикл while для удаления всех вхождений ‘pastrami’ из sandwich_orders. Убедитесь в том, что в finished_sandwiches значение ‘pastrami’ не встречается ни одного раза.

7-10. Отпуск мечты: напишите программу, которая опрашивает пользователей, где бы они хотели провести отпуск. Включите блок кода для вывода результатов опроса.

Итоги


В этой главе вы научились использовать input() для того, чтобы пользователи могли вводить собственную информацию в своих программах. Вы научились работать с числовыми и текстовыми данными, а также управлять продолжительностью выполнения своих программ с помощью циклов while. Также мы рассмотрели несколько способов управления циклами while: установку флага, команду break и команду continue. Вы узнали, как использовать цикл while для перемещения элементов из одного списка в другой и как удалить все вхождения некоторого значения из списка. Также были рассмотрены возможности применения циклов while со словарями.

Глава 8 посвящена функциям. Функции позволяют разделить программу на меньшие части, каждая из которых решает одну конкретную задачу. Функции можно хранить в отдельных файлах и вызывать их столько раз, сколько потребуется. Благодаря функциям вы сможете писать более эффективный код, более простой в отладке и сопровождении, который к тому же можно повторно использовать в разных программах.

8. Функции


Эта глава посвящена функциям — именованным блокам кода, предназначенным для решения одной конкретной задачи. Чтобы выполнить задачу, определенную в виде функции, вы указываете имя функции, отвечающей за эту задачу. Если задача должна многократно выполняться в программе, вам не придется заново вводить весь необходимый код; просто вызовите функцию, предназначенную для решения задачи, и этот вызов приказывает Python выполнить код, содержащийся внутри функции. Как вы вскоре убедитесь, использование функций упрощает чтение, написание, тестирование кода и исправление ошибок.

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