Теперь, когда мы понимаем переменные, мы можем приступить к разработке более сложных структур кода, которые могут встраивать более интересные функции в наши скрипты. До этого момента наши сценарии были довольно простыми и ограничивались выполнением только в порядке сверху вниз, с одной командой или операцией на строку. Следующие две концепции, условные выражения и циклы, представляют собой две основные структуры «управления потоком», которые могут фактически изменять последовательность, в которой выполняется наш код, тем самым создавая более сложное поведение и более интересные функции.

Условные

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

b = True
if b:
    print 'b is True'

Здесь, поскольку b на самом деле истинно, он проходит проверку, вызывая выполнение кода, вставленного после строки «if b:». Попробуйте запустить код еще раз, на этот раз установив b в значение False, чтобы убедиться, что ничего не происходит. В этом случае, если b не проходит проверку, весь блок кода вставки после первой условной строки пропускается и игнорируется. В этом коде ‘if b:’ является сокращением от ‘if b is True:’. Если вы хотите проверить ложность, вы можете использовать сокращение Python «if not b:» или написать полное «if b is False:».

В Python строка, оканчивающаяся на ’:’, за которой следуют вставленные строки кода, является основным синтаксисом для создания иерархической структуры и используется со всеми структурами кода более высокого уровня, включая условные выражения, циклы, функции и объекты. Хитрость в том, что Python очень разборчив в том, как эти вставки указываются. У вас есть возможность использовать TABS или серию пробелов, но вы не можете смешивать и сопоставлять, и вы должны очень четко указывать количество каждого из них, которое вы используете, в зависимости от уровня структуры. Например, этот код:

b = False
if b:
    print 'b is True'
    print 'b is False'

будет пропускать обе строки печати, если b имеет значение False. Однако, удалив отступ в последней строке, вы уберете эту строку из вложенной структуры, и теперь она будет выполняться независимо от того, имеет ли b значение True или False:

b = False
if b:
    print 'b is True'
print 'b is False'

С другой стороны, если вы вставите последнюю строку на один уровень дальше:

b = False
if b:
    print 'b is True'
        print 'b is False'

Вы получите сообщение об ошибке

IndentationError: unexpected indent

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

Двигаясь дальше, если условный тест не проходит и первый блок кода пропущен, его можно перехватить с помощью оператора else:

b = True
if b:
    print 'b is True'
else:
    print 'b is False'

В этом случае, когда b имеет значение True, будет выполняться первый оператор, а когда b равен False, будет выполняться второй оператор. Попробуйте использовать этот код в обоих направлениях.

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

num = 7
if num > 5:
    print 'num is greater than 5'

Или содержимое строки:

t = 'this is text'
if t == 'this is text':
    print 'the text matches'

В этом примере я использую оператор double equals ’==’, чтобы проверить, совпадает ли одно с другим. Это стандартный способ проверки равенства, поскольку единственное равно ’=’ зарезервировано для присвоения значений переменным. Наиболее распространенные операторы сравнения:

  • == (равно)
  • ! = (не равно)
  • > (лучше чем)
  • ›= (Больше или равно)
  • ‹= (Меньше или равно)

Вы можете использовать оператор «elif:» (объединение else и if), чтобы связать вместе условия для создания более сложной логики:

num1 = 3
num2 = 7
if num1 > 5:
    print 'num1 is greater than 5'
elif num2 > 5:
    print 'num2 is greater than 5'
else:
    print "they're both too small!"

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

Наконец, вы также можете объединить несколько тестов в одной строке, используя ключевые слова «и» и «или»:

num1 = 3
num2 = 7
if num1 < 5 and num2 < 5:
    print "they're both too small!"
if num1 < 5 or num2 < 5:
    print "at least one of them is too small!"

Петли

Циклы - это второй основной тип структуры «управления потоком», и они могут использоваться для многократного повторения кода при определенных условиях. Самый простой тип цикла - это цикл, который перебирает каждое значение в списке:

fruits = ['apples', 'oranges', 'bananas']
for fruit in fruits:
    print fruit

Структура ‘for item in list:’ - это основной способ построения циклов в Python. По сути, он запускает код вставки в структуре один раз для каждого элемента в списке, каждый раз устанавливая для текущего элемента переменную, указанную перед «in». В этом случае он будет запускать код «print» три раза, по одному для каждого фрукта в списке. Каждый раз, когда код запускается, переменная "fruit" устанавливается на разные фрукты в списке по порядку. Это часто используется для применения определенного вида анализа или обработки к каждому элементу в списке.

Вы можете выполнить такую ​​же базовую итерацию в словаре, используя функцию .keys (), которая вернет список всех ключей в словаре и позволит вам перебирать каждую запись:

dict = {'a': 1, 'b': 2, 'c': 3}
for key in dict.keys():
    print dict[key]

Если вы запустите этот код, вы увидите, что записи не возвращаются в том же порядке, в котором они вводятся. Это связано с тем, что словари, в отличие от списков, не устанавливают определенный порядок. Однако повторение ключей с помощью функции .key () гарантирует, что вы пройдете по каждому элементу в словаре.

В дополнение к итерации по каждому элементу в списке или словаре, циклы часто используются для простого повторения определенного фрагмента кода определенное количество раз. Для этого очень полезна функция Python range (), которая принимает целочисленное значение и возвращает список целых чисел, начиная с 0, вплоть до этого значения, но не включая его:

print range(5)

Используя функцию range (), мы можем настроить базовый цикл, например:

for i in range(5):
    print 'Hello'

Это просто запустит код внутри цикла пять раз, поскольку фактически мы создаем список из пяти последовательных чисел, а затем перебираем каждый элемент в этом списке. Кроме того, мы также сохраняем каждое последующее число в переменной «i», которую мы также можем использовать в цикле. Типичным примером является объединение обеих стратегий путем привязки функции range () к длине списка (с помощью функции len ()), а затем использования числа итерации для получения элементов из этого списка:

fruits = ['apples', 'oranges', 'bananas']
for i in range(len(fruits)):
    print fruits[i]

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

fruits = ['apples', 'oranges', 'bananas']
for i, fruit in enumerate(fruits):
    print 'the ' + fruit + ' are in position ' + str(i)

В то время как цикл for будет служить большинству целей, существует другой вид цикла, который будет перебирать фрагмент кода до тех пор, пока не будет выполнено определенное условие:

i = 0
while i < 5:
    print i
    i += 1

В этом случае цикл будет продолжаться, пока выполняется его условие, и остановится только тогда, когда переменная 'i' получит значение больше или равное 5. Этот тип цикла может быть полезен, если вы не знаете, как долго должен длиться цикл. быть запущенным, или если вы хотите сделать критерии завершения каким-то образом динамическими по сравнению с другими действиями в сценарии. Однако для этого требуется немного больше настроек, поскольку проверяемое значение должно быть сначала инициализировано (i = 0), а внутри цикла должен быть код, который изменяет это значение таким образом, чтобы оно в конечном итоге соответствовало критериям выхода. Обозначение ’+ =’ здесь является сокращением в Python для добавления значения к переменной. Вы можете написать то же самое в явном виде:

i = i + 1

Этот тип цикла по своей природе более опасен, чем цикл for, потому что он может легко создать ситуацию, когда цикл никогда не сможет выйти. Теоретически такой цикл будет выполняться бесконечно, хотя на практике он наверняка приведет к сбою Python. Самый опасный вид цикла - это и самый простой:

while True:
    print 'infinity'

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

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