Условные операторы в Python.

Содержание

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

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

Вот тут-то и появляются операторы управления. Операторы управления занимаются порядком выполнения выражений в программе (называемой потоком управления программы).

Вот что вы узнаете из этого урока: вы столкнетесь со своим первым оператором управления Python, оператором if.

В реальном мире мы обычно даем оценку информации вокруг нас, а затем выбираем тот или иной порядок действий на основе того, что мы наблюдаем:

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

В программе на Python оператор if — это способ принятия такого рода решений. Он допускает условное выполнение оператора или группы операторов на основе значения выражения.

В общих чертах этот урок выглядит следующим образом:

  • Во-первых, вы получите краткий обзор оператора if в его простейшей форме.
  • Далее, используя оператор if в качестве модели, вы увидите, почему операторы управления требуют некоторые механизмы для группировки отступов или блоков вместе. Вы узнаете, как это делается в Python.
  • Наконец, вы свяжете все это вместе и научитесь писать сложный код принятия решений.

Готовы? Поехали!

Знакомство с оператором If

Мы начнем с самого основного типа выражения if. Его простейшая форма:

if <expr>:
<statement>
if <expr>:
<statement>
if <expr>:
    <statement>

В форме, показанной выше:

  • <expr> — это оператор, вычисляемый в логическом контексте.
  • <statement> — это допустимый оператор Python,который должен иметь отступ. (Скоро вы поймете почему)
  • Если имеет значение true (вычисляется до значения "truthy"), то выполняется . Если имеет значение false, то пропускается и не выполняется.

    Обратите внимание, что двоеточие (:) после обязательно. Некоторые языки программирования требуют, чтобы был заключен в круглые скобки, но в Python это не нужно.

    Вот несколько примеров оператора if:

    x = 0
    y = 5
    if x < y: # Правда
    print('yes')
    if y < x: # Ложь
    print('yes')
    if x: # Ложь
    print('yes')
    if y: # Правда
    print('yes')
    if x or y: # Правда
    print('yes')
    if x and y: # Ложь
    print('yes')
    if 'aul' in 'grault': # Правда
    print('yes')
    if 'quux' in ['foo', 'bar', 'baz']: # Ложь
    print('yes')
    x = 0
    y = 5

    if x < y: # Правда
    print('yes')

    if y < x: # Ложь
    print('yes')

    if x: # Ложь
    print('yes')

    if y: # Правда
    print('yes')

    if x or y: # Правда
    print('yes')

    if x and y: # Ложь
    print('yes')

    if 'aul' in 'grault': # Правда
    print('yes')

    if 'quux' in ['foo', 'bar', 'baz']: # Ложь
    print('yes')

    x = 0
    y = 5
    
    if x < y:                            # Правда
        print('yes')
    
    
    if y < x:                            # Ложь
        print('yes')
    
    
    if x:                                # Ложь
        print('yes')
    
    if y:                                # Правда
        print('yes')
    
    
    
    if x or y:                           # Правда
        print('yes')
    
    
    if x and y:                          # Ложь
        print('yes')
    
    
    if 'aul' in 'grault':                # Правда
        print('yes')
    
    
    if 'quux' in ['foo', 'bar', 'baz']:  # Ложь
        print('yes')
    
    

    Примечание: Если вы пробуете эти примеры в интерактивном режиме в сеансе REPL, вы обнаружите, что при нажатии клавиши Enter после ввода оператора print('yes') ничего не произойдет.

    Поскольку это многострочный оператор, вам нужно нажать Enter во второй раз, чтобы сообщить интерпретатору, что вы закончили с ним. Эта дополнительная новая строка не нужна в коде, выполняемом из файла скрипта.

    Группировка операторов: отступы и блоки

    Пока все идет хорошо.

    Но предположим, что вы хотите вычислить условие, а затем сделать больше действий, если это правда:

    Если погода будет хорошая, то я буду:

  • Косить лужайку
  • Полоть огород
  • Гулять с собакой
  • (Если погода не будет хорошей, то я не буду делать ничего из этого)

    Во всех приведенных выше примерах за каждым if <expr>: следует только один оператор <statement>. Должен быть какой-то способ сказать: "если <expr> истина, то сделайте все следующие вещи"

    Обычный подход, используемый большинством языков программирования, заключается в определении синтаксического устройства, которое группирует несколько операторов в один составной оператор или блок. Блок рассматривается синтаксически как единое целое. Если он является целью оператора if и <expr> имеет значение истина, то выполняются все операторы в блоке. Если <expr> является ложным, то ни один из них не является ложным.

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

    Python: все дело в отступе

    Python следует условности, известной как правило off-side, термин, придуманный британским ученым-компьютерщиком Питером Дж. Языки, которые придерживаются правила off-side, определяют блоки отступом. Python — один из небольшого набора автономных языков.

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

    Таким образом, составной оператор if в Python выглядит следующим образом:

    if <expr>:
    <statement>
    <statement>
    ...
    <statement>
    <following_statement>
    if <expr>:
    <statement>
    <statement>
    ...
    <statement>
    <following_statement>
    if <expr>:
        <statement>
        <statement>
        ...
        <statement>
    <following_statement>
    

    Здесь все операторы на соответствующем уровне отступа (строки 2‑5) считаются частью одного блока. Весь блок выполняется, если <expr> имеет значение true, или пропускаются, если <expr> имеет значение false. В любом случае выполнение продолжается с <following_statement> (строка 6).

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

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

    Рассмотрим этот скрипт foo.py:

    if 'foo' in ['bar', 'baz', 'qux']:
    print('Выражение истина')
    print('Выполнение инструкции')
    print('...')
    print('Готово')
    if 'foo' in ['bar', 'baz', 'qux']:
    print('Выражение истина')
    print('Выполнение инструкции')
    print('...')
    print('Готово')
    if 'foo' in ['bar', 'baz', 'qux']:
        print('Выражение истина')
        print('Выполнение инструкции')
        print('...')
        print('Готово')
    

    После старта foo.py производит данный вывод:

    C:\Users\john\Documents>python foo.py
    After conditional
    C:\Users\john\Documents>python foo.py
    After conditional
    C:\Users\john\Documents>python foo.py
    After conditional
    

    Четыре оператора print () в строках 2-5 имеют отступы на одном уровне. Они составляют блок, который был бы выполнен, если бы условие было истинным. Но это ложь, поэтому все утверждения в блоке пропускаются. После завершения сложного оператора if (независимо от того, выполняются ли операторы в блоке в строках 2-5 или нет) выполнение переходит к первому оператору с меньшим уровнем отступа: оператору print() в строке 6.

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

    Вот более сложный файл сценария под названием blocks.py:

    # Does line execute? Да Нет
    # --- --
    if 'foo' in ['foo', 'bar', 'baz']: # x
    print('Условие имеет значение истина') # x
    if 10 > 20: # x
    print('Внутреннее состояние') # x
    print('Между внутренними условиями') # x
    if 10 < 20: # x
    print('Внутренние состояние 2') # x
    print('Окончание внешнего состояния') # x
    print('Через внешнее состояние') # x
    # Does line execute? Да Нет
    # --- --
    if 'foo' in ['foo', 'bar', 'baz']: # x
    print('Условие имеет значение истина') # x

    if 10 > 20: # x
    print('Внутреннее состояние') # x

    print('Между внутренними условиями') # x

    if 10 < 20: # x
    print('Внутренние состояние 2') # x

    print('Окончание внешнего состояния') # x
    print('Через внешнее состояние') # x

    # Does line execute?                        Да    Нет
    #                                           ---    --
    if 'foo' in ['foo', 'bar', 'baz']:        #  x
        print('Условие имеет значение истина')      #  x
    
        if 10 > 20:                           #  x
            print('Внутреннее состояние')        #        x
    
        print('Между внутренними условиями')     #  x
    
        if 10 < 20:                           #  x
            print('Внутренние состояние 2')        #  x
    
        print('Окончание внешнего состояния')       #  x
    print('Через внешнее состояние')            #  x
    

    Выходные данные, сгенерированные при запуске этого скрипта, показаны ниже:

    C:\Users\john\Documents>python blocks.py
    Outer condition is true
    Between inner conditions
    Inner condition 2
    End of outer condition
    After outer condition
    C:\Users\john\Documents>python blocks.py
    Outer condition is true
    Between inner conditions
    Inner condition 2
    End of outer condition
    After outer condition
    C:\Users\john\Documents>python blocks.py
    Outer condition is true
    Between inner conditions
    Inner condition 2
    End of outer condition
    After outer condition
    

    Примечание: Если вам интересно, то правило off-side является причиной необходимости дополнительной новой строки при вводе многострочных операторов в сеансе REPL. В противном случае интерпретатор не может знать, что последний оператор блока был введен.

    Что делают другие языки?

    Возможно, Вам интересно, какие существуют альтернативы. Как определяются блоки в языках, которые не придерживаются правила off-side?

    Тактика, используемая большинством языков программирования, заключается в назначении специальных маркеров, которые отмечают начало и конец блока. Например, в Perl блоки определяются с помощью пар фигурных скобок ({}) следующим образом:

    if (<expr>) {
    <statement>;
    <statement>;
    ...
    <statement>;
    }
    <following_statement>;
    if (<expr>) {
    <statement>;
    <statement>;
    ...
    <statement>;
    }
    <following_statement>;
    if (<expr>) {
        <statement>;
        <statement>;
        ...
        <statement>;
    }
    <following_statement>;
    

    C/C++, Java и целый ряд других языков используют фигурные скобки таким образом.

    Другие языки, такие как Algol и Pascal, используют ключевые слова begin и end для включения блоков.

    Что лучше?

    Лучшее — в глазах смотрящего. В целом программисты, как правило, довольно сильно переживают по поводу того, как они что-то делают. Споры о достоинствах правила офсайда могут разгораться довольно жарко.
    Достоинства:

  • Краткое и последовательное использование отступов Python.
  • В языках программирования, которые не используют правило off-side, отступ кода полностью не зависит от определения блока и функции кода. Можно написать код с отступом, который на самом деле не соответствует тому, как выполняется код, создавая тем самым ошибочное впечатление, когда человек просто смотрит на него. Такого рода ошибки практически невозможно сделать в Python.
  • Использование отступов для определения блоков заставляет Вас поддерживать стандарты форматирования кода, которые вы, вероятно, должны использовать в любом случае.
  • Недостатки:

  • Многие программисты не любят, когда их заставляют делать что-то определенным образом. Они имеют твердое мнение о том, что выглядит хорошо, а что нет, и им не нравится, когда их принуждают к определенному выбору.
  • Некоторые редакторы вставляют сочетание пробелов и символов табуляции слева от строк с отступами, что затрудняет интерпретатору Python определение уровней отступов. С другой стороны, часто можно настроить редакторы так, чтобы они этого не делали. Как правило, не считается желательным иметь смесь табуляций и пробелов в исходном коде, независимо от языка.
  • Нравится вам это или нет, но если вы программируете на Python, вы застряли с правилом off-side. Все структуры управления в Python используют его.

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

    Операторы else и elif

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

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

    if <expr>:
    <statement(s)>
    else:
    <statement(s)>
    if <expr>:
    <statement(s)>
    else:
    <statement(s)>
    if <expr>:
        <statement(s)>
    else:
        <statement(s)>
    

    Если <expr> имеет значение true, то выполняется первый набор, а второй пропускается. Если <expr> имеет значение false, то первый набор пропускается, а второй выполняется. В любом случае, выполнение затем возобновляется после второго набора. Оба набора определяются отступом, как описано выше.

    В этом примере x меньше 50, поэтому выполняется первый набор (строки 4-5), а второй набор (строки 7-8) пропускается:

    x = 20
    if x < 50:
    print('(первый набор)')
    print('x is small')
    else:
    print('(второй набор)')
    print('x is large')
    x = 20

    if x < 50:
    print('(первый набор)')
    print('x is small')
    else:
    print('(второй набор)')
    print('x is large')

    x = 20
    
    if x < 50:
        print('(первый набор)')
        print('x is small')
    else:
        print('(второй набор)')
        print('x is large')
    

    Здесь, с другой стороны, x больше 50, поэтому первый набор передается, а второй выполняется:

    x = 120
    if x < 50:
    print('(первый набор)')
    print('x is small')
    else:
    print('(второй набор)')
    print('x is large')
    x = 120

    if x < 50:
    print('(первый набор)')
    print('x is small')
    else:
    print('(второй набор)')
    print('x is large')

    x = 120
    
    if x < 50:
        print('(первый набор)')
        print('x is small')
    else:
        print('(второй набор)')
        print('x is large')
    

    Существует также синтаксис для выполнения ветвления, основанный на нескольких альтернативах. Для этого используйте одно или несколько предложений elif (сокращение от else if). Python вычисляет каждый <expr> по очереди и выполняет набор, соответствующий Первому, который является истинным. Если ни одно из выражений не является истиной и указано предложение else

    , то выполняется этот набор:

    if <expr>:
    <statement(s)>
    elif <expr>:
    <statement(s)>
    elif <expr>:
    <statement(s)>
    ...
    else:
    <statement(s)>
    if <expr>:
    <statement(s)>
    elif <expr>:
    <statement(s)>
    elif <expr>:
    <statement(s)>
    ...
    else:
    <statement(s)>
    if <expr>:
        <statement(s)>
    elif <expr>:
        <statement(s)>
    elif <expr>:
        <statement(s)>
        ...
    else:
        <statement(s)>
    

    Можно указать произвольное количество предложений elif. Предложение else является необязательным. Если есть, то он должен быть указан последним:

    name = 'Joe'
    if name == 'Fred':
    print('Hello Fred')
    elif name == 'Xander':
    print('Hello Xander')
    elif name == 'Joe':
    print('Hello Joe')
    elif name == 'Arnold':
    print('Hello Arnold')
    else:
    print("I don't know who you are!")
    name = 'Joe'
    if name == 'Fred':
    print('Hello Fred')
    elif name == 'Xander':
    print('Hello Xander')
    elif name == 'Joe':
    print('Hello Joe')
    elif name == 'Arnold':
    print('Hello Arnold')
    else:
    print("I don't know who you are!")
    name = 'Joe'
    if name == 'Fred':
        print('Hello Fred')
    elif name == 'Xander':
        print('Hello Xander')
    elif name == 'Joe':
        print('Hello Joe')
    elif name == 'Arnold':
        print('Hello Arnold')
    else:
        print("I don't know who you are!")
    

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

    Примечание: использование длинного ряда if/elif/else может быть немного неудобным, особенно когда действия представляют собой простые операторы, такие как print().

    Вот одна из возможных альтернатив приведенному выше примеру с использованием метода dict. get() :

    names = {
    'Fred': 'Hello Fred',
    'Xander': 'Hello Xander',
    'Joe': 'Hello Joe',
    'Arnold': 'Hello Arnold'
    }
    print(names.get('Joe', "I don't know who you are!"))
    print(names.get('Rick', "I don't know who you are!"))
    names = {
    'Fred': 'Hello Fred',
    'Xander': 'Hello Xander',
    'Joe': 'Hello Joe',
    'Arnold': 'Hello Arnold'
    }

    print(names.get('Joe', "I don't know who you are!"))

    print(names.get('Rick', "I don't know who you are!"))

    names = {
        'Fred': 'Hello Fred',
        'Xander': 'Hello Xander',
        'Joe': 'Hello Joe',
        'Arnold': 'Hello Arnold'
    }
    
    print(names.get('Joe', "I don't know who you are!"))
    
    print(names.get('Rick', "I don't know who you are!"))
    

    Вспомните из статьи про словари Python, что метод dict. get () ищет в словаре указанный ключ и возвращает соответствующее значение, если оно найдено, или заданное значение по умолчанию, если его нет.

    Оператор if с предложениями elif использует оценку короткого замыкания, аналогичную тому, что вы видели с операторами and и or. Как только одно из выражений оказывается истинным и его блок выполняется, ни одно из оставшихся выражений не проверяется. Это показано ниже:

    var # Not defined
    if 'a' in 'bar':
    print('foo')
    elif 1/0:
    print("This won't happen")
    elif var:
    print("This won't either")
    var # Not defined

    if 'a' in 'bar':
    print('foo')
    elif 1/0:
    print("This won't happen")
    elif var:
    print("This won't either")

    var  # Not defined
    
       
    if 'a' in 'bar':
        print('foo')
    elif 1/0:
        print("This won't happen")
    elif var:
        print("This won't either")
    
    

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

    Оператор If в одну строку

    Принято писать, если <expr> и <statement> с отступом на следующей строке, как это:

    if <expr>:
    <statement>
    if <expr>:
    <statement>
    if <expr>:
        <statement>
    

    Но допустимо написать целое утверждение if на одной строке. Будет выглядеть так:

    if <expr>: <statement>
    if <expr>: <statement>
    if <expr>: <statement>
    

    В одной строке может быть даже несколько <statement>, разделенных точкой с запятой:

    if <expr>: <statement_1>; <statement_2>; ...; <statement_n>
    if <expr>: <statement_1>; <statement_2>; ...; <statement_n>
    if <expr>: <statement_1>; <statement_2>; ...; <statement_n>
    

    Но что это значит? Есть два объяснения:

    1) Если <expr> имеет значение true, выполняется <statement_1>.

    Затем выполните команду <statement_2> ... <statement_n> безусловно, независимо от того, является ли <expr> истинным или нет.

    2) Если <expr> имеет значение true, выполните все действия <statement_1> ... <statement_n>. В противном случае не выполняйте ни одного из них.

    Python принимает последнее объяснение. Точка с запятой, разделяющая <expr>, имеет более высокий приоритет, чем двоеточие, следующее за <expr> — на компьютерном сленге точка с запятой, как говорят, связывается более плотно, чем двоеточие. Таким образом, <statement> рассматриваются как набор, либо все они выполняются, либо ни один из них не выполняется:

    if 'f' in 'foo': print('1'); print('2'); print('3')
    if 'z' in 'foo': print('1'); print('2'); print('3')
    if 'f' in 'foo': print('1'); print('2'); print('3')

    if 'z' in 'foo': print('1'); print('2'); print('3')

    if 'f' in 'foo': print('1'); print('2'); print('3')
    
    
    if 'z' in 'foo': print('1'); print('2'); print('3')
    

    Несколько операторов могут быть указаны в той же строке, что и предложение elif или else:

    x = 2
    if x == 1: print('foo'); print('bar'); print('baz')
    elif x == 2: print('qux'); print('quux')
    else: print('corge'); print('grault')
    x = 3
    if x == 1: print('foo'); print('bar'); print('baz')
    elif x == 2: print('qux'); print('quux')
    else: print('corge'); print('grault')
    x = 2
    if x == 1: print('foo'); print('bar'); print('baz')
    elif x == 2: print('qux'); print('quux')
    else: print('corge'); print('grault')

    x = 3
    if x == 1: print('foo'); print('bar'); print('baz')
    elif x == 2: print('qux'); print('quux')
    else: print('corge'); print('grault')

    x = 2
    if x == 1: print('foo'); print('bar'); print('baz')
    elif x == 2: print('qux'); print('quux')
    else: print('corge'); print('grault')
    
    
    x = 3
    if x == 1: print('foo'); print('bar'); print('baz')
    elif x == 2: print('qux'); print('quux')
    else: print('corge'); print('grault')
    

    Хотя все это работает, и интерпретатор допускает это, но обычно это не рекомендуется, потому что это приводит к плохой читабельности, особенно для сложных операторов if. PEP 8 (pep8 – это модуль, позволяющий проверять, соответствует ли код определенному стандарту)специально рекомендует этого не делать.

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

    x = 3
    if x == 1:
    print('foo')
    print('bar')
    print('baz')
    elif x == 2:
    print('qux')
    print('quux')
    else:
    print('corge')
    print('grault')
    x = 3
    if x == 1:
    print('foo')
    print('bar')
    print('baz')
    elif x == 2:
    print('qux')
    print('quux')
    else:
    print('corge')
    print('grault')
    x = 3
    if x == 1:
        print('foo')
        print('bar')
        print('baz')
    elif x == 2:
        print('qux')
        print('quux')
    else:
        print('corge')
        print('grault')
    
    

    Однако если оператор if достаточно прост, то размещение всего этого в одной строке может быть разумным.

    debugging = True # Установите значение True, чтобы включить отладку.
    .
    .
    .
    if debugging: print('About to call function foo()')
    foo()
    debugging = True # Установите значение True, чтобы включить отладку.

    .
    .
    .

    if debugging: print('About to call function foo()')
    foo()

    debugging = True  # Установите значение True, чтобы включить отладку.
    
        .
        .
        .
    
    if debugging: print('About to call function foo()')
    foo()
    

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

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

    В своей простейшей форме синтаксис условного выражения выглядит следующим образом:

    <expr1> if <conditional_expr> else <expr2>
    <expr1> if <conditional_expr> else <expr2>
    <expr1> if <conditional_expr> else <expr2>
    

    Это отличается от форм операторов if, перечисленных выше, потому что это не управляющая структура направляет поток выполнения программы. Он действует скорее как оператор, определяющий выражение. В приведенном выше примере сначала вычисляется <conditional_expr>. Если истина, то выражение вычисляется как <expr1>. Если ложь, то выражение вычисляется как <expr2>.

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

    raining = False
    print("Let's go to the", 'beach' if not raining else 'library')
    raining = True
    print("Let's go to the", 'beach' if not raining else 'library')
    age = 12
    s = 'minor' if age < 21 else 'adult'
    s
    'yes' if ('qux' in ['foo', 'bar', 'baz']) else 'no'
    raining = False
    print("Let's go to the", 'beach' if not raining else 'library')

    raining = True
    print("Let's go to the", 'beach' if not raining else 'library')

    age = 12
    s = 'minor' if age < 21 else 'adult'
    s

    'yes' if ('qux' in ['foo', 'bar', 'baz']) else 'no'

    raining = False
    print("Let's go to the", 'beach' if not raining else 'library')
    
    raining = True
    print("Let's go to the", 'beach' if not raining else 'library')
    
    
    age = 12
    s = 'minor' if age < 21 else 'adult'
    s
    
    
    'yes' if ('qux' in ['foo', 'bar', 'baz']) else 'no'
    
    

    Примечание: условное выражение Python аналогично синтаксису <conditional_expr> ? <expr1> : <expr2>, используемому многими другими языками-C, Perl и Java. На самом деле, оператор ?: обычно называют тернарным оператором в этих языках, что, вероятно, является причиной того, что условное выражение Python иногда называют тернарным оператором Python.

    Вы можете видеть в PEP 308 (PEP 308 — Условные выражения), что синтаксис <conditional_expr> ? <expr1> : <expr2> был рассмотрен для Python, но в конечном счете отвергнут в пользу синтаксиса, показанного выше.

    Обычно условное выражение используется для выбора назначения переменной. Например, предположим, что вы хотите найти большее из двух чисел. Конечно, есть встроенная функция max (), которая делает именно это (и многое другое), что вы могли бы использовать. Но предположим, вы хотите написать свой собственный код с нуля.

    Вы можете использовать стандартный оператор if с предложением else:

    if a > b:
    m = a
    else:
    m = b
    if a > b:
    m = a
    else:
    m = b
    if a > b:
        m = a
    else:
        m = b
    
    

    Но условный оператор короче и, возможно, более читабельнее:

    m = a if a > b else b
    m = a if a > b else b
    m = a if a > b else b
    
    

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

    В следующем примере оператор + связывается более плотно, чем условное выражение, поэтому сначала вычисляются ++x и y+2y + 2, а затем условное выражение. Скобки во втором случае не нужны и результат не меняется:

    x = y = 40
    z = 1 + x if x > y else y + 2
    z
    z = (1 + x) if x > y else (y + 2)
    z
    x = y = 40

    z = 1 + x if x > y else y + 2
    z

    z = (1 + x) if x > y else (y + 2)
    z

    x = y = 40
    
    z = 1 + x if x > y else y + 2
    z
    
    
    z = (1 + x) if x > y else (y + 2)
    z
    

    Если вы хотите, чтобы условное выражение было вычислено первым, вам нужно окружить его группирующими скобками. В следующем примере сначала вычисляется (x, если x > y, иначе y). В результате получается y, который равен 40, поэтому присваивается z 1+40+21 + 40 + 2 = 43:

    x = y = 40
    z = 1 + (x if x > y else y) + 2
    z
    x = y = 40

    z = 1 + (x if x > y else y) + 2
    z

    x = y = 40
    
    z = 1 + (x if x > y else y) + 2
    z
    

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

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

    В выражении <expr1>, если <conditional_expr> иначе <expr2>:

  • Если <conditional_expr> правда, <expr1> и <expr2> не вычисляется.
  • Если <conditional_expr> имеет значение false, то возвращается <expr2> и <expr1> не вычисляется.
  • Вы можете проверить это, используя термины, которые вызвали бы ошибку:

    'foo' if True else 1/0
    1/0 if False else 'bar'
    'foo' if True else 1/0

    1/0 if False else 'bar'

    'foo' if True else 1/0
    
    1/0 if False else 'bar'
    

    В обоих случаях условия 1/0 не оцениваются, поэтому никаких исключений не возникнет.

    Условные выражения также могут быть объединены вместе, как своего рода альтернативная структура if/elif/else, как показано здесь:

    s = ('foo' if (x == 1) else
    'bar' if (x == 2) else
    'baz' if (x == 3) else
    'qux' if (x == 4) else
    'quux'
    )
    s
    s = ('foo' if (x == 1) else
    'bar' if (x == 2) else
    'baz' if (x == 3) else
    'qux' if (x == 4) else
    'quux'
    )
    s
    s = ('foo' if (x == 1) else
         'bar' if (x == 2) else
         'baz' if (x == 3) else
         'qux' if (x == 4) else
         'quux'
    )
    s
    

    Неясно, имеет ли это какое-либо существенное преимущество перед соответствующим оператором if/elif/else, но это синтаксически правильно для Python.

    Оператор pass в Python

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

    В языках, где разделители токенов используются для определения блоков, таких как фигурные скобки в Perl и C, пустые разделители могут использоваться для определения заглушки кода. Например, ниже приведен рабочий код Perl или C:

    # This is not Python
    if (x)
    {
    }
    # This is not Python
    if (x)
    {
    }
    # This is not Python
    if (x)
    {
    }
    

    Здесь пустые фигурные скобки определяют пустой блок. Perl или C оценят выражение x, а затем, даже если оно истина, ничего не произойдет.

    Поскольку в Python используются отступы, а не разделители, то не возможно указать блок пустым. Если вы вводите оператор if с if <expr>:, то что-то должно идти сразу после него, либо в той же строке, либо с отступом в следующей строке.

    Рассмотрим этот скрипт foo.py:

    if True:
    print('foo')
    if True:

    print('foo')

    if True:
    
    print('foo')
    

    После этого, вы получите:

    C:\Users\john\Documents\Python\doc>python foo.py
    File "foo.py", line 3
    print('foo')
    ^
    IndentationError: expected an indented block
    C:\Users\john\Documents\Python\doc>python foo.py
    File "foo.py", line 3
    print('foo')
    ^
    IndentationError: expected an indented block
    C:\Users\john\Documents\Python\doc>python foo.py
      File "foo.py", line 3
        print('foo')
            ^
    IndentationError: expected an indented block
    

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

    if True:
    pass
    print('foo')
    if True:
    pass

    print('foo')

    if True:
        pass
    
    print('foo')
    

    Сейчас foo.py работает без ошибок:

    C:\Users\john\Documents\Python\doc>python foo.py
    foo
    C:\Users\john\Documents\Python\doc>python foo.py
    foo
    C:\Users\john\Documents\Python\doc>python foo.py
    foo
    

    Вывод

    С завершением этого урока вы начинаете писать код Python, который выходит за рамки простого последовательного выполнения:

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

    В следующих двух статьях будут представлены две новые структуры управления: оператор while и оператор for. Эти помощники облегчат повторение, многократное выполнение оператора или блока операторов.

    Оригинал статьи: Conditional Statements in Python

    263

    Нужно войти чтобы оставить комментарий.