До настоящего момента мы работали только с одним фрагментом информации, полученной от пользователя. Мы получали ввод пользователя, а затем выводили ответ на него. При следующем проходе цикла 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
. .