Циклы в программировании. Цикл while

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

Цикл while

"While" переводится с английского как "пока". Но не в смысле "до свидания", а в смысле "пока имеем это, делаем то".

Можно сказать, while является универсальным циклом. Он присутствует во всех языках, поддерживающих структурное программирование, в том числе в Python. Его синтаксис обобщенно для всех языков можно выразить так:

while логическое_выражение {
    выражение 1;
    … 
    выражение n;
}

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

В случае while, после того как его тело выполнено, поток возвращается к заголовку цикла и снова проверяет условие. Если логическое выражение возвращает истину, то тело снова выполняется. Потом снова возвращаемся к заголовку и так далее.

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

Рассмотрите блок-схему цикла while.

Блок-схема цикла while

На ней ярко-голубыми прямоугольниками обозначена основная ветка программы, ромбом – заголовок цикла с логическим выражением, бирюзовым прямоугольником – тело цикла.

С циклом while возможны две исключительные ситуации:

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

  • Если логическое выражение в заголовке while никогда не возвращает False, а всегда остается равным True, то цикл никогда не завершится, если только в его теле нет оператора принудительного выхода из цикла (break) или вызовов функций выхода из программы – quit(), exit() в случае Python. Если цикл повторяется и повторяется бесконечное количество раз, то в программе происходит зацикливание. В это время она зависает и самостоятельно завершиться не может.

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

Другими словами, если бы программа предполагала дальнейшие действия с числом (например, проверку на четность), а она его не получила, то единственное, что программа могла сделать, это закончить свою работу досрочно.

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

n = input("Введите целое число: ")
 
while type(n) != int:
    try:
        n = int(n)
    except ValueError:
        print("Неправильно ввели!")
        n = input("Введите целое число: ")
 
if n % 2 == 0:
    print("Четное")
else:
    print("Нечетное")

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

Примечание 2. В выражении type(n) != int с помощью функции type() проверяется тип переменной n. Если он не равен int, т. е. значение n не является целым числом, а является в данном случае строкой, то выражение возвращает истину. Если же тип n равен int, то данное логическое выражение возвращает ложь.

Примечание 3. Оператор % в языке Python используется для нахождения остатка от деления. Так, если число четное, то оно без остатка делится на 2, т. е. остаток будет равен нулю. Если число нечетное, то остаток будет равен единице.

Проследим алгоритм выполнения этого кода. Пользователь вводит данные, они имеют строковый тип и присваиваются переменной n. В заголовке while проверяется тип n. При первом входе в цикл тип n всегда строковый, т. е. он не равен int. Следовательно, логическое выражение возвращает истину, что позволяет зайти в тело цикла.

Здесь в ветке try совершается попытка преобразования строки к целочисленному типу. Если она была удачной, то ветка except пропускается, и поток выполнения снова возвращается к заголовку while.

Теперь n связана с целым числом, следовательно, ее тип int, который не может быть не равен int. Он ему равен. Таким образом логическое выражение type(n) != int возвращает False, и весь цикл завершает свою работу. Далее поток выполнения переходит к оператору if-else, находящемуся в основной ветке программы. Здесь могло бы находиться что угодно, не обязательно условный оператор.

Вернемся назад. Если в теле try попытка преобразования к числу была неудачной, и было выброшено исключение ValueError, то поток выполнения программы отправляется в ветку except и выполняет находящиеся здесь выражения, последнее из которых просит пользователя снова ввести данные. Переменная n теперь имеет новое значение.

После завершения except снова проверяется логическое выражение в заголовке цикла. Оно даст True, т. к. значение n по-прежнему строка.

Выход из цикла возможен только тогда, когда значение n будет успешно конвертировано в число.

Рассмотрим следующий пример:

total = 100
 
i = 0
while i < 5:
    n = int(input())
    total = total - n
    i = i + 1
 
print("Осталось", total)

Сколько раз "прокрутится" цикл в этой программе, т. е. сколько итераций он сделает? Ответ: 5.

  1. Сначала переменная i равна 0. В заголовке цикла проверяется условие i < 5, и оно истинно. Тело цикла выполняется. В нем меняется значение i, путем добавления к нему единицы.

  2. Теперь переменная i равна 1. Это меньше пяти, и тело цикла выполняется второй раз. В нем i меняется, ее новое значение 2.

  3. Два меньше пяти. Тело цикла выполняется третий раз. Значение i становится равным трем.

  4. Три меньше пяти. На этой итерации i присваивается 4.

  5. Четыре по прежнему меньше пяти. К i добавляется единица, и теперь ее значение равно пяти.

Далее начинается шестая итерация цикла. Происходит проверка условия i < 5. Но поскольку теперь оно возвращает ложь, то выполнение цикла прерывается, и его тело не выполняется.

"Смысловая нагрузка" данного цикла – это последовательное вычитание из переменной total вводимых чисел. Переменная i в данном случае играет только роль счетчика итераций цикла. В других языках программирования для таких случаев предусмотрен цикл for, который так и называется: "цикл со счетчиком". Его преимущество заключается в том, что в теле цикла не надо изменять переменную-счетчик, ее значение меняется автоматически в заголовке for.

В языке Python тоже есть цикл for. Но это не цикл со счетчиком. В Питоне он предназначен для перебора элементов последовательностей и других сложных объектов. Данный цикл и последовательности будут изучены в последующих уроках.

Для while наличие счетчика не обязательно. Представим, что надо вводить числа, пока переменная total больше нуля. Тогда код будет выглядеть так:

total = 100
 
while total > 0:
    n = int(input())
    total = total - n
 
print("Ресурс исчерпан")

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

Самое главное для цикла while – чтобы в его теле происходили изменения значений переменных, которые проверяются в его заголовке, и чтобы хоть когда-нибудь наступил случай, когда логическое выражение в заголовке возвращает False. Иначе произойдет зацикливание.

Примечание 1. Не обязательно в выражениях total = total - n и i = i + 1 повторять одну и ту же переменную. В Python допустим сокращенный способ записи подобных выражений: total -= n и i += 1.

Примечание 2. При использовании счетчика он не обязательно должен увеличиваться на единицу, а может изменяться в любую сторону на любое значение. Например, если надо вывести числа кратные пяти от 100 до 0, то изменение счетчика будет таким i = i - 5, или i -= 5.

Примечание 3. Для счетчика не обязательно использовать переменную с идентификатором i. Можно назвать переменную-счетчик как угодно. Однако так принято в программировании, что счетчики обозначают именами i и j (иногда одновременно требуются два счетчика).

Практическая работа

  1. Измените последний код из урока так, чтобы переменная total не могла уйти в минус. Например, после предыдущих вычитаний ее значение стало равным 25. Пользователь вводит число 30. Однако программа не выполняет вычитание, а выводит сообщение о недопустимости операции, после чего осуществляет выход из цикла.

  2. Используя цикл while, выведите на экран для числа 2 его степени от 0 до 20. Возведение в степень в Python обозначается как **. Фрагмент вывода:

    ...
      32
      64
     128
     256
     512
    1024
    ...

Примеры решения в android-приложении и pdf-версии курса.

Создано

Обновлено

Комментарии

кодовый замок с тремя попытками ввода с последующей блокировкой

cod=3458 #код
m=0 #счетчик попыток
n=0
print("введите код, после третеи попытки замок заблокируется")
while m<=3:
    n=int(input()) #ввод с клавиатуры
    m=m+1
    if n==cod:
        print("open")
        break;
    if not n==cod:
        print("не верно повторите ввод")
    if m==3:
        print("lock") # число попыток превышено, замок заблокирован

помогите мне пожалуйста как написать программу по этой задаче:

Цикл while. Существует четыре пользователя, у каждого пользователя есть логин и пароль. Запрашивать ввод логина и пароля пока не совпадут пара пользователь-пароль. Вывести приветствие пользователя с использованием логина.

Ребят, прошу сразу не кидаться на меня. В 25 годов решил хоть чуть приблизиться к программированию. Ни в школе, ни в универе как такого программирования не было, а если и было, то все забыто напрочь. Так вот, в практическом задании, с числами Ф, надо вывести с 5 члена по 12. В общем-то все понятно, i это сколько раз цикл крутанет, n собственно количество циклов. Как мне начать именно с 5 члена?

Ответ на от Макс

итерируемые объекты бывают разные - бывают уже подсчитанные, а бывают генераторы, которые и сами не знают, сколько там объектов. во втором случае, пока не запросишь первые 4, то не получишь.

а в случае списков и прочего - есть срезы

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

путь 1 - получить первые 20 чисел, записать в out, взять срез с 5 по 20:

def fib_gen():
    a, b = 0, 1
    while True:
        yield b
        a, b = b, a+b
 
fib = fib_gen()
 
out = []
for n in range(20):
    out.append(next(fib))
 
print (out)
#[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
 
print (out[4:])
#[5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]

тут мы получаем результат в out, а потом делаем нужный срез. out - весь список с 20 значением. out[4:] - этот же список с 5 по 20 (нумерация идёт с 0)

путь 2 - обрабатываем значения, но выводим результат только с 1 по 20:

def fib_gen():
    a, b = 0, 1
    while True:
        yield b
        a, b = b, a+b
 
fib = fib_gen()
 
# неверно записывать
#for n in range(20):
#    if n >= 4:
#        print (next(fib))
 
for n in range(20):
    out = next(fib)
    if n >= 4:
        print (out)

вообще, для запроса у генераторов нужного количества элементов есть функция islice в модуле itertools:
https://docs.python.org/3/library/itertools.html

from itertools import islice
 
def fib_gen():
    a, b = 0, 1
    while True:
        yield b
        a, b = b, a+b
 
out = islice(fib_gen(),4,20)
 
print (list(out))

весь код для python3. в python2 вместо next(элемент) используется элемент.next()

Ответ на от Макс

Количество прокруток (итераций) цикла while i < n равно разности n - i.
Чтобы начать с 5-го элемента, надо i присвоить 5 до цикла. А n должно быть равно 12. Могут быть нюансы, связанные с

  • индексацией элементов (она начинается с 0, значит пятый элемент имеет индекс 4, т. е. i надо присвоить 4);
  • нужен или не нужен 12-й элемент (i < n или i <= n и т. п.).

name = str()
while name != str('n') and name != str('y'):
    name = str(raw_input('Тебе нравится учить Python? введите "y" или "n"'))
if name == str('y'):
    print('Ура!')
elif name == str('n'):
    print('Жаль :(')
else:
    print('error')

Вот такой вот кодик с циклом, спасибо!

Ответ на от Дмитрий

1. зачем везде напиханы str? в python 2 все строки по-умолчанию имеют тип str, то есть набор байт. при этом и y, и n, в этот набор байт попадают, поэтому для python2 это просто пустое преобразование. в python 3 все строки по умолчанию уникодные (тип str), а второпитоновый str - теперь bytes. поэтому опять же и 'y', str('y') - это одно и то же.

2. else: никогда не выполнится. ибо из while выход будет только тогда, когда name будет y или n

Как написать программу что бы при каждом прохождение while ответ записывался в новую переменную s1=, s2=, s3= и так далее.

a=int(1)
b=int(2)
c=int(10)
while a < c:
    a=a*b
    print(a)
 
# вот такой ответ. 
# s1=2
# s2=4
# s3=8
# s4=16

Ответ на от Владислав

> Как написать программу что бы при каждом прохождение while ответ записывался в новую переменную s1=, s2=, s3= и так далее.

зачем? это какой-то грубый хак. не проще ли использовать list или dict?

вообще, это можно сделать вот так:

cntr = 0
a=int(1)
b=int(2)
c=int(10)
while a < c:
    a=a*b
    cntr += 1
    locals()['s%s' % cntr] = a
    print(a)

но это явно пример неверно поставленной задачи

подскажите, почему?
зад.3
без i не работает?
расчет времени движения. если без i, то не получается добиться чтобы пльзователь вводил данные до момента введения положительных чисел.

s=int(input("s"))
v=int(input("v"))
t=s%v
i=0
while t<i:
    print("eще раз")
    s=int(input("s"))
    v=int(input("v"))
    t=s%v
    i=i+1
if t>0:
    print(t)

Ответ на от Гость

Попробуйте вот так:

while 1:
    s=int(input("s"))
    v=int(input("v"))
    t=s//v
    if t > 0:
        print(t)
        break
    print("eще раз")

Хотя программу можно построить как угодно. Например, в Питоне у while есть необязательная часть else. Можно ее использовать:

s=int(input("s"))
v=int(input("v"))
t=s//v
while t<0:
    print("eще раз")
    s=int(input("s"))
    v=int(input("v"))
    t=s//v
else:
    print(t)

И % - это нахождение остатка, // - деление нацело, / - обычное деление.

Ответ на от Гость

Тут вообще разложение числа на простые множители

import sys
import math
 
def prime_factorize(n):
    factors = []
    number = math.fabs(n)
 
    while number > 1:
        factor = get_next_prime_factor(number)
        factors.append(factor)
        number /= factor
 
    if n < -1:
        factors[0] = -factors[0]
 
    return tuple(factors)
def get_next_prime_factor(n):
    if n % 2 == 0:
        return 2
    for x in range(3, int(math.ceil(math.sqrt(n)) + 1), 2):
        if n % x == 0:
            return x
 
    return int(n)
 
if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: %s <integer>" % sys.argv[0])
        exit()
 
    try:
        number = int(sys.argv[1])
    except ValueError:
        print("'%s' is not an integer!" % sys.argv[1])
    else:
        print("%d -> %s" % (number, prime_factorize(number)))

Подскажите, а цикл while не поддерживает множественное условие?
То есть, нужна такая программа: предложение ввести целое число от 1 до 3. Если пользователь ввел правильное число ( либо 1, либо 2, либо 3), то вывести сообщение типа Ура, молодец. Если неправильное - предложить ввести еще раз.
Я сначала придумал такой код, но он не работает:

number = int (input ("Введите целое число от  1 до 3"))
while number!=1 or number!=2 or number!=3:
    print ("Вы ввели неправильное число")
    number = int (input ("Введите число от  1 до 3"))
print ("Вы ввели правильное число!")

Если оставить только 1 условие (проверка равенства только одному числу), то программа работает. А при нескольких условиях не работает.

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

Ответ на от Mihey

Программа работает неправильно, потому что если, например, ввести число 2, то уже проверка number!=1 дает True и все остальное условие проверять необязательно.

Условия при while могут быть такими (на выбор):

  • number not in (1,2,3)
  • not(0 < number < 4)

Ответ на от plustilino

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

number = int(input ("Введите целое число от 1 до 3:  "))
while number not in (1,2,3):
   print ("Вы ввели неправильное число")
   number = int(input ("Введите целое число от 1 до 3:  "))
print ("УРА!")

Подскажите, пожалуйста, почему код:

chet = 0
max = 20
while chet < max:
   if (chet / 2 == 0):
      print (chet)
   chet = chet + 1

выдаёт

0
1

а не список четных чисел до 20?

неправильное сложение то ли в цикле while, то ли в самом питоне 3,3
скрипт для подбора значений(нужно было подобрать цену, что бы получилось ровное количество товара(товар не может быть с десятыми, а цена с тысячными)

z=236000
x=24.00
while x<=26:
    print(x,'\t', z/x)
    x=x+0.01

вырезка из результатов ответа:

...
24.0 	 9833.333333333334
24.01 	 9829.23781757601
24.020000000000003 	 9825.145711906744
24.030000000000005 	 9821.057012068246
24.040000000000006 	 9816.971713810313
24.050000000000008 	 9812.889812889809
24.06000000000001 	 9808.811305070652
24.07000000000001 	 9804.7361861238
24.080000000000013 	 9800.664451827237
...

почему х принимает такие странные значения

подскажите, как можно написать программу, которая спрашивает у пользователя слово и число и выводит на экран введённое слово введённое число раз.Пробовала, никак не выходит (((

Ответ на от Гость

#!/usr/bin/env python
name = raw_input("word: ")
number=int(input('number: '))
number=number+1
s=1
while s < number:
    print " - " + name + ""
    s=s+1
#! /usr/bin/env python
# coding: utf-8
word = raw_input("Введи слово: ")
number=int(input('Введи число: '))
print (" " + word + "") * number

Правильно решил?
total = 100
 
while total > 0:
    n = int(input())
    if total >= n:
        total -= n
        print('Остаток:', total)
    else:
        print('Недопустимая операция')
 
print('Ресурс исчерпан')