Цикл while в Python (неопределенная итерация)

Содержание

Итерация — выполнение одного и того же блока кода снова и снова. Конструкция программирования, реализующая итерацию, называется циклом.

В программировании есть два типа итераций: неопределенные и определенные:

  • При неопределенной итерации количество выполнений цикла заранее не указывается. Назначенный блок выполняется повторно, пока выполняется какое‑либо условие.
  • При определенной итерации, в момент запуска цикла указывается количество раз выполнения указанного блока.
  • В этом уроке вы:

    • Узнаете о цикле while, конструкции управления Python, используемой для неопределенной итерации
    • Узнаете, как преждевременно выйти из цикла или итерации цикла
    • Исследуете бесконечные циклы

    По окончании вы должны хорошо понимать, как использовать неопределенную итерацию в Python.

    Цикл while


    Давайте посмотрим, как используется оператор while для построения циклов в Python. Мы начнем с более простого и будем усложнять.

    Характер элементарного цикла while показан ниже:

    while :
         <statement(s)>
    

    statement(s) представляет собой блок для многократного выполнения, часто называется телом цикла. Обозначается отступом, как в операторе if.

    Запомните: все конструкции управления в Python используют отступы для определения блоков.

    Управляющая конструкция  — expr обычно включает в себя одну или несколько переменных, которые инициализируются до начала цикла, а затем изменяются где-то в теле цикла.

    Когда встречается while цикл, expr сначала оценивается в логическом контексте. Если это правда, тело цикла выполняется. Затем expr проверяется снова, и если это опять правда, то выполняется снова. Это продолжается до тех пор, пока expr станет ложью, после чего выполнение программы переходит к первому оператору после тела цикла.

    Рассмотрим этот цикл:

    
    while < expr >:
        < statement(s) >
    
    

    Вот что происходит в этом примере:

    • n изначально равно 5. Выражение в while заголовке оператора n > 0 имеет значение true, поэтому тело цикла выполняется. Внутри тела цикла n уменьшается на 1 до 4 и затем печатается.
    • Когда тело цикла завершено, выполнение программы возвращается к началу цикла, и выражение проверяется снова. Оно все еще true, поэтому тело выполняется снова и 3 печатается.
    • Это продолжается до тех пор, пока не n станет 0. В этот момент, когда выражение проверяется, оно ложно, и цикл завершается.

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

    n = 5
    while n > 0:
        n -= 1
        print(n)
    

    В приведенном выше примере, когда встречается цикл, n равно 0. Управляющее выражение n > 0 уже ложно, поэтому тело цикла никогда не выполнится.
    Вот еще один while цикл, включающий список, а не числовое сравнение:

    a = ['foo', 'bar', 'baz']
    while a:
        print(a.pop(-1))
    

    Когда список оценивается в логическом контексте, он является истинным, если в нем есть элементы, и ложным, если он пуст. В этом примере a истинно, пока в нем есть элементы. После того, как все элементы будут удалены с помощью метода .pop () и список будет пуст, a примет значение «false», и цикл завершится.

    Операторы Python break и continue

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

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

    Различие между break и continue показано на рисунке:

    Это файл скрипта с именем break.py который демонстрирует работу оператора break:

    n = 5
    while n > 0:
        n -= 1
        if n == 2:
            break
        print(n)
    print('Цикл завершен.')
    

    Запуск break.py из интерпретатора командной строки приводит к следующему результату:

    C:\Users\pythonguru\Documents>python break.py
    4
    3
    Цикл завершен.
    

    Когда n станет равно 2, break оператор выполняется, цикл полностью завершается, и выполнение программы переходит к print() оператору.
    Следующий скрипт continue.py идентичен, за исключением continue оператора вместо break:

    n = 5
    while n > 0:
        n -= 1
        if n == 2:
            continue
        print(n)
    print('Цикл завершен.')
    

    Вывод continue.py выглядит так:

    C:\Users\pythonguru\Documents>python continue.py
    4
    3
    1
    0
    Цикл завершен.
    

    На этот раз, когда n равно 2, continue оператор вызывает завершение этой итерации.
    Таким образом, 2 не печатается. Выполнение возвращается к началу цикла, условие переоценивается, и оно все еще выполняется. Цикл возобновляется, завершается, когда n становится 0, как ранее.

    Условный оператор else

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

    while :
        <statement(s)>
    else:
        <additional_statement(s)>
    

    additional_statement(s, указанный в условии else, будет выполняться , когда прервётся цикл while.

    У вас может возникнуть вопрос: «Чем это полезно?». Вы можете сделать то же самое, поместив эти операторы сразу после while цикла, без else:

    while <expr>:
        <statement(s)>
    <additional_statement(s)>
    

    Какая разница?

    В последнем случае, без else, additional_statement(s) будет выполняться после завершения while цикла, несмотря ни на что.

    Когда условия помещены в else, они будут выполняться только в том случае, если цикл завершается «по истощению», то есть, если цикл повторяется до тех пор, пока условие управления не станет ложным. Если цикл завершается break оператором, условие else не будет выполнено.

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

    n = 5
    while n > 0:
        n -= 1
        print(n)
    else:
        print('Цикл выполнен.')
    

    В этом случае цикл повторялся до тех пор, пока условие не стало false: n стало 0, а условие n > 0 стало ложным. Поскольку цикл прожил свою естественную жизнь, так сказать, условие else было выполнено. Теперь обратите внимание на разницу здесь:

    n = 5
    while n > 0:
        n -= 1
        print(n)
        if n == 2:
            break
    else:
        print('Цикл выполнен.')
    

    Этот цикл преждевременно завершается с помощью break, поэтому else не выполняется.

    Может показаться, что значение слова else не совсем соответствует while циклу, а также if оператору. Гвидо ван Россум, создатель Python, сказал, что, если бы он начал сначала, то исключил бы условие else цикла while из языка.

    Какая-нибудь из следующих интерпретаций может помочь сделать ее более понятной:

    • Думайте о заголовке цикла (while n > 0) как об if операторе (if n > 0), который выполняется снова и снова, и else выполняется, когда условие становится false.
    • Думайте об else, как если бы это был nobreak, поскольку следующий блок выполняется, если не был break.

    Если вы не найдете ни одну из этих интерпретаций полезной, просто проигнорируйте их.

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

    a = ['foo', 'bar', 'baz', 'qux']
    s = 'corge'
    
    i = 0
    while i < len(a):
        if a[i] == s:
            # Processing for item found
            break
        i += 1
    else:
        # Processing for item not found
        print(s, 'not found in list.')
    

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

    Прежде всего, списки обычно обрабатываются с определенной итерацией, а не while циклом. Определенная итерация (for) рассматривается в следующем уроке.

    Во-вторых, Python предоставляет встроенные способы поиска элемента в списке. Вы можете использовать in оператор:

    if s in a:
        print(s, 'found in list.')
    else:
        print(s, 'not found in list.')
    

    list.index() метод также будет работать. Этот метод вызывает исключение ValueError, если элемент не найден в списке, поэтому для его использования необходимо понимать обработку исключений. В Python вы используете try оператор для обработки исключения. Пример приведен ниже:

    try:
        print(a.index('corge'))
    except ValueError:
        print(s, 'not found in list.')
    

    Вы узнаете об обработке исключений позже.

    Условие else с циклом while — это немного странное, редко встречающееся явление. Но не избегайте его, в некоторых ситуациях else может внести ясность в ваш код!

    Бесконечные циклы

    Предположим, вы пишете while цикл, который теоретически никогда не заканчивается. Звучит странно, не правда ли?

    Рассмотрим этот пример:

    while True:
        print('foo')
    

    Этот код был завершен сочетанием Ctrl+C , которое вызывает прерывание с помощью клавиатуры.Или это продолжалось бы бесконечно.

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

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

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

    Вот еще один вариант показанного выше цикла, который последовательно удаляет элементы из списка, .pop() пока он не станет пустым:

    a = ['foo', 'bar', 'baz']
    while True:
        if not a:
            break
        print(a.pop(-1))
    

    Когда a становится пустым, not a становится истинным, и break оператор выходит из цикла.

    Вы также можете указать несколько break операторов в цикле:

    while True:
        if <expr1>:  # One condition for loop termination
            break
        ...
        if <expr2>:  # Another termination condition
            break
        ...
        if <expr3>:  # Yet another
            break
    

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

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

    Вложенные циклы while

    Управляющие конструкции Python могут быть вложены друг в друга. Например, условные операторы if/elif/else могут быть вложенными:

    if age < 18:
        if gender == 'M':
            print('son')
        else:
            print('daughter')
    elif age >= 18 and age < 65:
        if gender == 'M':
            print('father')
        else:
            print('mother')
    else:
        if gender == 'M':
            print('grandfather')
        else:
            print('grandmother')
    

    Точно так же while цикл может содержаться в другом while цикле, как показано здесь:

    a = ['foo', 'bar']
    while len(a):
        print(a.pop(0))
        b = ['baz', 'qux']
        while len(b):
            print('>', b.pop(0))
    

    Оператор break или continue, найденный во вложенных циклах, применяется к ближайшему охватывающему циклу:

    while <expr1>:
        statement
        statement
    
        while <expr2>:
            statement
            statement
            break  # Applies to while <expr2>: loop
    
        break  # Applies to while e<xpr1>: loop
    

    Кроме того, while циклы могут быть вложены в if/elif/else операторы, и наоборот:

    if <expr>:
        statement
        while <expr>:
            statement
            statement
    else:
        while <expr>:
            statement
            statement
        statement
    
    while <expr>:
        if <expr>:
            statement
        elif <expr>:
            statement
        else:
            statement
    
        if <expr>:
            statement
    

    Фактически, все управляющие кострукции Python могут смешиваться друг с другом в любой степени, в какой вам угодно. Так и должно быть. Представьте, как было бы неприятно, если бы были ограничения, такие как «while цикл не может быть заключен в if оператор» или «while циклы могут быть вложены друг в друга не более чем на четыре глубины». Вам было бы очень трудно помнить все.
    Казалось бы, произвольные числовые или логические ограничения считаются признаком плохого дизайна программного языка. К счастью, в Python этого не много.

    Однолинейные циклы while


    Как и в if операторе, while цикл может быть указан в одной строке. Если в блоке, составляющем тело цикла, есть несколько операторов, они могут быть разделены точкой с запятой (;):

    n = 5
    while n > 0: n -= 1; print(n)
    
    

    Это работает только с простыми утверждениями, вы не сможете объединить два составных оператора в одну строку. Таким образом, вы можете указать while цикл в одной строке, как указано выше, и пишете if оператор в одной строке:

    if True: print('foo')
    
    

    Но вы не можете сделать так:

    while n > 0: n -= 1; if True: print('foo')
    
    

    Помните, что PEP 8препятствует нескольким утверждениям в одной строке. Поэтому, вам не желательно делать так очень часто.

    Вывод


    В этом блоке вы узнали о неопределенной итерации с помощью цикла Python while. Теперь вы можете:

    • Строить основные и сложные while циклы
    • Выполнить цикл с break и continue
    • Использовать else с while циклом
    • Разбираться с бесконечными циклами

    Теперь вы должны хорошо понимать, как выполнить фрагмент кода повторно.
    ОРИГИНАЛ СТАТЬИ

    Оставить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *