Урок 6. Создаем циклы с помощью ключевых слов while и for

While и for - циклы повторяющие операции более чем один раз.

Урок 6. Создаем циклы с помощью ключевых слов while и for

Проверки с помощью if, elif и else выполняются последовательно, одна за другой. Иногда определенные операции требуется выполнить более чем один раз. Для этого нужен цикл, и Python предлагает два варианта: while и for.

Повторяем действия с помощью цикла while

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

>>> count = 1
>>> while count <= 5:
...     print(count)
...     count += 1
...
1
2
3
4
5
>>>

Сначала мы присваиваем значение 1 переменной count. Цикл while сравнивает значение переменной count с числом 5 и продолжает работу, если значение переменной count меньше или равно 5. Внутри цикла мы выводим значение переменной count, а затем увеличиваем его на 1 с помощью выражения count+=1. Python возвращается к началу цикла и снова сравнивает значение переменной count с числом 5. Значение переменной count теперь равно 2, весь цикл while проходит очередной раз, и затем переменная count увеличивается до 3.

Так продолжается до тех пор, пока переменная count не будет увеличена с 5 до 6 в нижней части цикла. Во время очередного возвращения к началу цикла проверка count<=5 вернет значение False и цикл while закончится. Python перейдет к выполнению следующих строк.

Прерываем цикл с помощью оператора break

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

>>> while True:
...     stuff = input("String to capitalize [type q to quit]: ")
...     if stuff == "q":
...         break
...     print(stuff.capitalize())
...
String to capitalize [type q to quit]: test
Test
String to capitalize [type q to quit]: hey, it works
Hey, it works
String to capitalize [type q to quit]: q
>>>

Пропускаем итерации, используя оператор continue

Иногда вам нужно не прерывать весь цикл, а пропустить по какой-либо причине только одну итерацию. Рассмотрим пример: прочитаем целое число, и если оно четное, выведем на экран его значение в квадрате, если же нечетное — пропустим его. Мы даже добавим несколько комментариев. И вновь для выхода из цикла используем строку q:

>>> while True:
...     value = input("Integer, please [q to quit]: ")
...     if value == 'q':      # выход
...         break
...     number = int(value)
...     if number % 2 == 0:  # нечетное число
...         continue
...     print(number, "squared is", number*number)
...
Integer, please [q to quit]: 1
1 squared is 1
Integer, please [q to quit]: 2
Integer, please [q to quit]: 3
3 squared is 9
Integer, please [q to quit]: 4
Integer, please [q to quit]: 5
5 squared is 25
Integer, please [q to quit]: q
>>>

Проверяем, завершился ли цикл раньше, с помощью блока else

Если цикл while завершился нормально (без вызова break), управление передается в опциональный блок else. Вы пользуетесь этим, когда кодируете цикл так, чтобы, выполняя некоторую проверку, он прервался, как только проверка успешно выполнится. Блок else запустится в том случае, если цикл while пройдет полностью, но искомый объект так и не будет найден:

>>> numbers = [1, 3, 5]
>>> position = 0
>>> while position < len(numbers):
...     number = numbers[position]
...     if number % 2 == 0:
...         print('Found even number', number)
...         break
...     position += 1
... else:  # break не вызываем
...     print('No even number found')
...
No even number found

Такое использование ключевого слова else может показаться нелогичным. Воспринимайте его как проверку на прерывание цикла.

Выполняем итерации с использованием ключевых слов for и in

В Python итераторы часто используются по одной простой причине. Они позволяют вам проходить структуры данных без знания того, насколько эти структуры велики и как реализованы. Вы даже можете обратиться к данным, которые были созданы во время работы программы. Это позволяет обрабатывать потоки данных, которые в противном случае не поместились бы в память компьютера.

Чтобы продемонстрировать итерирование, нам нужно что-то, по чему можно проитерировать. Вы уже познакомились со строками в уроке 5, но пока не знаете всей информации о других итерабельных объектах, таких как списки и кортежи (урок 7) или словари (урок 8). Сейчас я покажу два способа итерирования по строке, а итерирование по другим типам рассмотрим на соответствующих уроках.

Вполне возможно пройти по строке таким образом:

>>> word = 'thud'
>>> offset = 0
>>> while offset < len(word):
...     print(word[offset])
...     offset += 1
...
t
h
u
d

Однако существует более характерный для Python способ решения этой задачи:

>>> for letter in word:
...     print(letter)
...
t
h
u
d

Итерирование по строке возвращает один символ за раз.

Прерываем цикл с помощью оператора break

Оператор break прерывает цикл for точно так же, как и цикл while.

>>> word = 'thud'
>>> for letter in word:
...     if letter == 'u':
...         break
...     print(letter)
...
t
h

Пропускаем итерации, используя оператор continue

Добавление ключевого слова continue в цикл for позволяет перейти на следующую итерацию цикла, как и в случае с циклом while.

Проверяем, завершился ли цикл раньше, с помощью блока else

Как и в цикле while, в for имеется опциональный блок else, который проверяет, выполнился ли цикл for полностью. Если ключевое слово breakне было вызвано, будет выполнен блок else.

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

>>> word = 'thud'
>>> for letter in word:
...     if letter == 'x':
...         print("Eek! An 'x'!")
...         break
...     print(letter)
... else:
...     print("No 'x' in there.")
...
t
h
u
d
No 'x' in there

Как и в цикле while, в цикле for использование блока else может показаться нелогичным. Можно рассматривать цикл for как поиск чего-либо, а появление else — как сигнал, что вы ничего не нашли. Чтобы получить тот же эффект без блока else, используйте переменную, которая будет показывать, нашелся ли искомый элемент в цикле for.

Генерируем числовые последовательности с помощью функции range()

Функция range() выбирает поток чисел в заданном диапазоне без необходимости создавать и сохранять крупную структуру данных, такую как список или кортеж. Это позволяет создавать большие диапазоны, не используя всю память на вашем компьютере и не сбивая программу.

Функцию range() можно применять так же, как функцию slice(): range(начало,конец,шаг). Если вы опустите значение начало, диапазон начнется с 0. Обязательным является только значение конец: как и в случае со slice(), последнее учтенное значение будет прямо перед конец. Значение по умолчанию шаг равно 1, но вы можете изменить его на –1.

Как и zip(), функция range() возвращает итерабельный объект, поэтому вам нужно пройти по значениям с помощью конструкции for...in или преобразовать объект в последовательность, такую как список. Создадим диапазон 0, 1, 2:

>>> for x in range(0,3):
...     print(x)
...
0
1
2
>>> list(range(0, 3))
[0, 1, 2]

Вот так можно создать диапазон от 2 до 0:

>>> for x in range(2, -1, -1):
...     print(x)
...
2
1
0
>>> list(range(2, -1, -1))
[2, 1, 0]

В следующем фрагменте кода шаг равен 2, что позволяет получить все четные числа от 0 до 10:

>>> list(range(0, 11, 2))
[0, 2, 4, 6, 8, 10]

Прочие итераторы

В уроке 10 вы увидите, как использовать итерирование для объектов, которые вы сами определили. На уроке 11 мы рассмотрим itertools — стандартный модуль Python, содержащий множество удобных функций.

Упражнения

6.1. Используйте цикл for, чтобы вывести на экран значения списка [3,2,1,0].

6.2. Присвойте значение 7 переменной guess_me и значение 1 переменной number. Напишите цикл while, который сравнивает переменные number и guess_me. Выведите строку 'меньше', если значение переменной start меньше значения переменной guess_me. Если значение переменной number равно значению переменной guess_me, выведите строку 'нашел!' и выйдите из цикла. Если значение переменной number больше значения переменной guess_me, выведите строку 'упс!' и выйдите из цикла. Увеличьте значение переменной number на выходе из цикла.

6.3. Присвойте значение 5 переменной guess_me. Используйте цикл for для того, чтобы проитерировать с помощью переменной number по диапазону range(10). Если значение переменной number меньше, чем значение guess_me, выведите на экран сообщение 'меньше'. Если оно равно значению guess_me — выведите сообщение 'Нашел!', а затем выйдите из цикла. Если значение переменной number больше, чем guess_me, выведите на экран сообщение 'oops' и выйдите из цикла.