§7. Инструкции циклов. Цикл while. Инструкции break и continue

Инструкции циклов

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

  • Цикл while
  • Цикл итераций по последовательности for
Цикл while является универсальным; в python эта инструкция реализует алгоритмическую структуру «цикл с предусловием». Блок-схема:

Однократное выполнение инструкций цикла (шаг) называется итерацией. В python не реализована алгоритмическая структура цикл с постусловием. Эту роль будет выполнять цикл while. В большинстве своем, различные типы циклов взаимозаменяемы.

Инструкция while

Инструкция цикла while в языке python имеет следующий синтаксис:

while логическое выражение:
    инструкции1
[else:
    инструкции2]

Пока логическое выражение истинно, будут выполняются инструкции в теле цикла. Логическое выражение — это булевское выражение результатом вычисления которого является True или False. Вместо булевского выражения может быть любое выражение скалярного типа. Если результатом вычисления такого выражения является значение отличное от нуля, то это интерпретируется как «истина», в противном случае — как «ложь». Если логическое выражение приобретает ложное значение, то будет выполнен необязательный блок после else.
Примечание. Блок else не будет выполняться, если цикл прерывается инструкцией break или continue (см. ниже). Обратите внимание, что блок else будет выполнятся и в том случае, если условие ложно изначально!
Программа 7.1

i = 0
while i < 10:
    i+=1
    print(i, end=' ')
else:
    print("\nЦикл звершил свою работу!" \
          "\nКоличество итераций -", i)
1 2 3 4 5 6 7 8 9 10
Цикл звершил свою работу!
Количество итераций 10

Примечание. Для переноса части логической строки (в исходном коде программы) используется символ "\". После этого символа необходимо перейти на новую (физическую) строку, т. е. нажать на клавишу Enter.
Сложность программирования такого типа цикла заключается в том, что разработчику необходимо продумывать изменение параметров в теле цикла так, чтобы эти изменения влияли на завершение цикла. Иначе говоря, результатом вычисления логического выражения должно стать, когда-нибудь, значение False. Неверно составленный программный код может привести к «зацикливанию» (т. е. невозможности выхода из цикла).
В некоторых случаях требуется реализация «бесконечного цикла». Это можно сделать, например, таким образом:

while True:
    Инструкции

Выход из «бесконечного» цикла можно реализовать с помощью инструкций if и break (см. ниже).
В отличие от других языков программирования (например, C++), блок в инструкции циклов и if не определяет область видимости данных. Переменные, с которыми связываются некоторые значения, как внутри блока, так и вне его — имеют глобальную видимость по отношению к программе (в данном модуле). Python по местоположению операции "=" связывает имя с конкретным пространством имен. Локальную область видимости имеют переменные (и другие объекты), которые определяются внутри блока функций — def. Об этом мы будем говорить позднее. Если требуется определить некоторый объект без инициализации применяется такая форма:

var = None

Накопители суммы и произведения

В циклах часто приходится выполнять действия получения (накопления) суммы или произведения. Для этих целей используются накопители. Примером такого накопителя является счетчик, который увеличивает значение (считает шаги цикла) на единицу с каждой итерацией (программа 7.1). Для использования таких накопителей переменная (целого или вещественного типа) принимает начальное значение "0" для накопления суммы и начальное значение "1" для накопления произведения вне тела цикла (до начала цикла). Пример использования счетчика и накопителя произведения в следующей задаче.
Постановка задачи: Вывести на экран все целые степени числа 2 от 1 до 10.
Программа 7.2

i = 0
p = 1
while i < 10:
    i+=1
    p*=2
    print('{:d} ^ {:2d} = {:d}'.format(2, i, p))
2 ^  1 = 2    
2 ^  2 = 4    
2 ^  3 = 8    
2 ^  4 = 16   
2 ^  5 = 32   
2 ^  6 = 64   
2 ^  7 = 128  
2 ^  8 = 256  
2 ^  9 = 512  
2 ^ 10 = 1024

Эту программу можно переписать с использованием операции побитового сдвига влево на 1 (ранее мы уже говорили об этой операции). Тогда инструкцию в строке 5 нужно переписать так:
p = p << 1 или p <<= 1
Циклы, возможно, не были столь полезны, если бы отсутствовала возможность обработки потока данных. В следующем классе задач в теле цикла используется инструкция if.
Постановка задачи. Вывести ряд двузначных чисел, сумма разрядов которых кратна 3 и определить сумму членов этого ряда.
Программа 7.3

i = 10
s = 0
while(i < 100):
    if (i // 10 + i % 10) % 3 == 0:
        print(i, end = ' ')
        s += i
    i+=1
print("\ns =", s)
12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 
s = 1665

Использование в цикле while случайных чисел

В некоторых задачах, в качестве "источника" данных, удобно применять генератор псевдо-случайных чисел. Реализация этого генератора находится в модуле random. Этот модуль содержит довольно много различных функций. В программе 4 используется функция randint. Эта функция имеет два аргумента randint(a, b), которые, собственно, определяют отрезок множества целых чисел из которого будут получены случайные числа: [a, b]. Более подробные сведения об использовании генератора случайных чисел мы дадим на следующем уроке.
Используя генератор случайных чисел получить числовой ряд из промежутка от a до b включительно, в количестве 100 элементов. Определить, каких чисел больше - четных или нечетных в этом ряде? Если таких чисел равное количество, то вывести 0. Выведите числовую последовательность в виде прямоугольной таблицы - матрицы 10х10.
Программа 7.4

from random import randint 
a = int(input("a = "))
b = int(input("b = "))
i, j = 0, 0
while i < 100:
    i += 1
    k = randint(a, b)
    print(k, end = ' ')
    if not k % 2: 
        j += 1
    if not i % 10: 
        print()
if j > 100 - j: 
    print("\nКоличество четных больше")
elif j == 50: 
    print("\n0")
else: 
    print("\nКоличество нечетных больше")
a = 10
b = 99
62 44 52 57 34 53 82 78 53 22 
91 82 79 66 75 62 63 50 40 66 
57 38 27 56 83 98 50 16 95 48 
25 98 66 50 50 87 12 18 13 80 
96 39 80 96 80 59 50 50 13 84 
76 57 86 52 16 25 13 62 62 27 
48 46 89 60 51 71 65 68 86 86 
46 32 26 74 65 57 89 91 37 45 
89 31 54 91 17 80 87 88 84 41 
20 59 67 37 37 47 29 85 73 44

Количество четных больше

Инструкции break и continue

break

Существует класс задач в которых производится анализ цифр в числе. Рассмотрим подобный пример в программе 7.5.
Дано число целое число n. Определить, имеются ли в числе две равные цифры, находящиеся в соседних разрядах. Например 10221, или 355, или 770.
Программа 7.5

n = int(input("n = "))
f = False
while n // 10 != 0:
    if n % 10 == n // 10 % 10:
        f = True
        break
    n //= 10
print("Такие цифры есть" if f else "Таких чисел нет")
n = 2113456789
Такие цифры есть

Примечание. Логические переменные применяются в качестве флагов, фиксирующих некоторое состояние объектов в программе. Их использование не обязательно, но выглядят они более элегантно и делают код более понятным.
В программе 7.5, чтобы прервать цикл (если найдены две одинаковые цифры), используется инструкция break. Инструкция break прерывает выполнение цикла while и for и передает управление программой инструкции, следующей за блоком цикла. Пример.
Постановка задачи: Дано натуральное число n. Определить, является ли оно простым.
Программа 7.6

i = 2
k = True
n = int(input("n = "))
while i <= n / 2:
    if n % i == 0:
        k = False
        break
    i+=1
print("Число", n, ("простое" if k else "не является простым"))
n = 23
Число 23 простое

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

continue

В отличие от break - continue прерывает выполнение только текущей итерации и передает выполнение на вычисление условия. При этом инструкции, следующие за continue до конца блока, игнорируются. Данная инструкция применяется не часто, но может быть использована, например, для контроля допустимости значений в выражениях тела цикла. Требуется вывести значения функции f(x) = 1 / x с шагом 1 (протабулировать) на отрезке от -20 до 20. Значение x == 0, в котором функция неопределена, должно быть пропущено.
Программа 7.7

i = -20
while i <= 20:
    if i == 0:
        i+=1
        continue
    print("{:+7.4f}".format(1/i))
    i+=1
...
-0.1667
-0.2000
-0.2500
-0.3333
-0.5000
-1.0000
+1.0000
+0.5000
+0.3333
+0.2500
+0.2000
+0.1667
...

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

Циклы while вложенные друг в друга

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

Решим классическую задачу. Дано целое n. Разложить число n на простые множители.
Программа 7.8

n = int(input('n = '))
i = 2
while i < n // 2:
    while not n % i:
        print(i, end=' ')
        n //= i
    i += 1 
n = 1000
2 2 2 5 5 5 

Идея алгоритма в следующем. Во внешнем цикле мы перебираем возможные делители числа. Во вешнем цикле мы делим число на делитель, пока это возможно.

Домашняя работа
  1. Составить программу. Вводится натуральное число N. Найти сумму и произведение всех натуральных чисел от 1 до N
  2. Составить программу. Вводятся натуральные число n, n > 10 и цифра k. Определить сумму цифр числа, а также есть ли цифра k в числе n.
Print Friendly, PDF & Email

Comments are closed