В данной лекции рассматривается инструкция ветвления (также называемая условной инструкцией и условным оператором) языка программирования Python, которая обеспечивает выполненение определенной последовательности команд в зависимости от некоторых условий. После нее мы поговорим о циклах - специальных инструкциях, позволяющих многократно выполнять один и тот же набор команд.
Инструкция ветвления в языке программирования Python имеет следующий вид:
if if_condition: if_code_block elif elif_condition_1: elif_code_block_1 ... elif elif_condition_N: elif_code_block_N else: else_code_block
Она должна содержать одно предложение if
и может содержать ноль или более предложений elif
, а также необязательное предложение else
.
Каждый из компонентов сondition в инструкции ветвления представляет собой некоторое выражение, о котором можно сказать, является оно истинным (принимает значение True
) или ложным (принимает значение False
). Это означает, что в качестве condition может быть использовано любое выражение, результатом которого является значение с типом bool
или значение, тип которого может быть неявно преобразован интерпретатором к типу bool
.
Каждый из компонентов code_block представляет собой последовательность любых инструкций языка Python, в том числе инструкций ветвления и циклов. Обратите внимание, что все инструкции, входящие в эти блоки кода должны иметь одинаковый ненулевой отступ относительно стоящего сверху предложения if
, elif
или else
. Общепринятым является использование четырех пробелов в качестве отступа. Среда разработки Jupyter Notebook упрощает написание кода, самостоятельно расставляя отступы нужного размера там, где требуется.
Принцип работы условной инструкции следующий:
elif
отсутствуют, интерпретатор выполняет else_code_block, если есть предложение else
, и завершает обработку инструкции ветвленияПриведем простейший пример инструкции ветвления:
s1 = 'abc'
s2 = 'abc'
if s1 == s2:
print('this string is printed only if s1 equals s2')
print('this too')
print('this string is always printed')
this string is printed only if s1 equals s2 this too this string is always printed
В данном примере мы намеренно не самым красивым образом оформили текст нашей программы, чтобы продемонстрировать важность правильной расстановки отступов при использовании инструкции ветвления. Первые две функции print
имеют отступ относительно нее, и поэтому являются частью if_code_block, а следовательно выполняются только при истинности условия s1 == s2
. Последняя функция print
не имеет отступа относительно if
, поэтому не является частью if_code_block и выполняется всегда независимо от истинности условия.
В следующем примере демонстрируется, как используется неявное преобразование типа из int
в bool
, которое выполняется интерпретатором потому, что выражение встречается в контексте, где ожидается булевое значение (мы упоминали кратко о таком преобразовании в главе Операции, но отложили его рассмотрение):
a = 13
# остаток от деления на 2 равен либо 1 (преобразуется в True), если число нечетное,
# или 0 (преобразуется в False), если четное
if a % 2:
print('a is odd')
else:
print('a is even')
a is odd
month_number = 5
if month_number > 2 and month_number < 6:
print('it\'s spring') # нужно экранировать символ ' внутри строки
elif month_number > 5 and month_number < 9:
print('it\'s summer')
elif month_number > 8 and month_number < 12:
print('it\'s autumn')
else:
print('winter is coming')
it's spring
Небольшие инструкции ветвления иногда заменяют условными выражениями, имеющими следующий синтаксис:
expression1 if condition else expression2
Результатом условного выражения становится результат выражения expression1, если codition равно True
, или результат выражения expression2 в противном случае. Приведем пример условного выражения, возвращающего большее из двух чисел:
a = 10
b = 20
max_value = a if a > b else b
max_value
20
Цикл - это специальная конструкция в языках программирования, позволяющая организовать многократное выполнение одного и того же блока кода. В языке Python существуют две инструкции для организации циклов: while
и for ... in
.
Рассмотрим синтаксис инструкции while
:
while condition: while_code_block else: else_code_block
Предложение else
является необязательным. Компоненты condition и code_block имеют тот же вид и смысл, что и аналогичные для инструкции ветвления. Если в code_block цикла содержится другой цикл, то он называется вложенным по отношению к первому.
Рассмотрим принцип работы инструкции while
:
True
, выполняет все инструкции из блока while_code_block, а затем повторяет действия этого пункта с началаelse
, и если оно есть, выполняет блок else_code_blocka = 0
while a <= 5:
print(a)
a += 1
else:
print('end')
print('next instruction')
0 1 2 3 4 5 end next instruction
С циклами while
в Python связана распространенная ошибка: если выражение condition никогда не возвращает False
, то цикл выполняется вечно, следовательно программа "зависает":
a = 0
# в следующем цикле мы забыли увеличить значение a, поэтому оно всегда будет 0, следовательно
# условие a < 10 всегда дает True и цикл выполняется вечно
while a < 10:
print(a)
# эта строчка никогда не выполнится
print('all printed')
Напомним, что если вы допустили ошибку, в результате которой программа зависает, то можно прервать ее выполнение с помощью команды Interrupt в меню Kernel.
Инструкция for ... in
может использоваться только для специальных итерируемых (iterable) типов данных. Итерируемым называется тип, представляющий собой набор из множества элементов, к которым можно обращаться по отдельности в некотором порядке. Мы уже знакомы с одним итерируемым типом - это строковый тип str
. Много других мы узнаем в лекции, посвященной коллекциям.
Рассмотрим синтаксис инструкции for ... in
:
for expression in iterable: for_code_block else: else_code_block
Как и для инструкций if
и while
, часть else
инструкции for ... in
является необязательной.
Компонент expression представляет собой переменную, которой при выполнении цикла в качестве значения поочередно присваивается каждый элемент из итерируемого типа iterable. Тип этой переменной будет тем же, что и тип элемента из iterable. В случае строкового типа str
, тип каждого отдельного символа в ней тоже str
.
Опишем принцип работы инструкции for ... in
:
else
, и если оно есть, выполняет блок else_code_blockРассмотрим пример, в котором мы дублируем каждый символ строки:
s = '0123456789'
result = '' # это переменная, в которую мы постепенно будем записывать продублированные символы из s
for symbol in s:
result += symbol * 2 # symbol имеет тип str, используем строковую операцию дублирования
result
'00112233445566778899'
В Python существуют инструкции break
и continue
, предназаначенные для изменения последовательности выполнения команд цикла. Обе они могут использоваться только внутри инструкций циклов while
и for ... in
(в их code_block), в противном случае интерпретатор генерирует исключение SyntaxError
:
a = 1
break
File "<ipython-input-7-d945458bb9f0>", line 2 break ^ SyntaxError: 'break' outside loop
Инструкция continue
говорит интерпретатору, что вместо того, чтобы выполнить следующие после нее инструкции цикла, он должен перейти в его начало. Инструкция break
означает, что нужно завершить выполнение цикла и перейти на следующую после него инструкцию в коде. Если программа выходит из цикла по инструкции break
, то блок кода, написанный в части else
, не выполняется.
s = 'test string. this part will not be processed'
result = ''
# копируем в result все символы, кроме буквы 't'
# если встречаем символ '.', то прекращаем обработку строки s
# обратите внимание, что continue и break является частью блока кода инструкций ветвления,
# потому что нам нужно, чтобы они выполнялись только при истинности соответствующих условий
for symbol in s:
if symbol == '.':
break # по условию задачи, нам больше не нужно обрабатывать строку s, поэтому
# выходим из цикла
if symbol == 't':
continue # нам не нужна эта буква, поэтому мы не хотим, чтобы следующая строчка была
# выполнена и даем интерпретатору команду вернуться в начало цикла
result += symbol
else:
print('whole string processed') # сообщение, что строка s полностью обработана НЕ будет
# выведено, если программа вышла из цикла с помощью break
print(result) # на эту строчку мы переходим, когда заканчивается выполнение инструкции for
es sring
Инструкция continue
используется довольно редко, потому что, как правило, можно обойтись без нее, причем программа станет выглядеть лучше и понятнее. Например, в предыдущем примере мы могли бы написать так:
if symbol != 't':
result += symbol
Инструкция break
напротив используется регулярно, например в случаях, если необходимо прервать выполнение цикла при наступлении некоторой ошибочной ситуации:
while main_condition: do something if error_occurred: break do something if error_occurred: break ...
В заключение отметим, что инструкции break
и continue
оказывают влияние только непосредственно на тот цикл, внутри которого они встречаются. Рассмотрим такой пример:
a = 0
b = 0
while a < 3:
print('a =', a)
a += 1
while b < 3: # инструкция break, которая идет внутри этого цикла, оказывает влияние только на него
print('b =', b)
break
b += 1
a = 0 b = 0 a = 1 b = 0 a = 2 b = 0
Как только во внутреннем цикле выполняется инструкция break
, интерпретатор завершает его работу, то есть инструкция b += 1
не обрабатывается. Мы говорили, что после завершения цикла интерпретатор переходит на следующую после него инструкцию. В случае, когда break
встречается во вложенном цикле, следующей инструкцией становится либо следующая после вложенного цикла инструкция внешнего цикла, либо, если такой инструкции нет (как в нашем случае), интерпретатор переходит в начало внешнего цикла.
for ... in
, один из которых вложен в другой. Внешний цикл for ... in
проходит по всем символам превоначальной строки, а внутренний - по специальной строке, содержащей только гласные. В результате выполнения внутреннего цикла можно определить, присутствует ли текущий символ среди гласных символов, и принять на основании этого решение, добавлять его в результат или нет.