Python
.pdfИли можно вместо not (b < 0) записать (b >= 0).
Операторы сравнения
Как правило, в качестве проверяемого условия используется результат вычисления одного из следующих операторов сравнения:
< Меньше #условие верно, если первый операнд меньше второго.
> Больше #условие верно, если первый операнд больше второго.
<= - меньше или равно.
>= - больше или равно.
== - равенство. #Условие верно, если два операнда равны.
!= - неравенство. #Условие верно, если два операнда неравны.
20
РАЗДЕЛ 2
Ветвления и оператор выбора
Оператор ветвления — конструкция в языках программирования, которая обеспечивает выполнение определённой команды или набора команд только при истинности некоторого логического выражения; либо выполнение одной из нескольких команд (наборов команд) в зависимости от значения некоторого выражения.
Блок-схема алгоритма с ветвлением показана на рис.1. Когда выражение в блоке "Условие" истинно, программа выполнит ''Действия ДА'', соответствующие ветви "ДА". В противном случае, то есть выражение ложно, будут выполнены ''Действия НЕТ''. В связи с этим условие необходимо составлять таким образом, чтобы выражение могло принимать только два значения — True или False.
В случае, когда одна проверка не может охватить все варианты, можно использовать "вложенные" условия, как показано на рис. 2. Уровень вложенности условий не ограничен, то есть они могут быть вложены друг в друга любое количество раз. Такая ситуация также называется "выбор".
Условная инструкция if-elif-else (оператор ветвления) — основной инструмент выбора в Python. Благодаря ей мы
можем задать, какое действие нужно выполнить при определенных значениях переменных в момент проверки логического условия.
Сначала идет обязательная часть if с условием, далее могут следовать (но не обязательно должны быть) одна или более частей elif и часть else. Общая схема такой конструкции if выглядит таким образом:
if <условие 1>:
<действие 1>
elif <условие 2>:
<действие 2>
else:
<действие 3>
Пример использования:
a = int(input())
if a < 50:
print('Плохо')
elif 50 <= a <= 85:
print('Хорошо')
else:
21
print('Отлично')
В данной программе на вход подается результат теста ученика а и выводится одна из трех фраз.
Приведенная ниже конструкция довольно простая, но, несмотря на это, громоздкая, так как занимает много строк:
if X:
A = 5
else:
A = 7
В таких случаях можно использовать выражение if/else:
A = 5 if X else 7
В данной строке интерпретатор, если X – истинно, присвоит А значение 5, иначе — 7. Вместо чисел можно так же записать некоторые выражения.
Задача.
На вход подается значение температуры t. Необходимо вывести "Хорошая погода!", при t больше 10º , или "Плохая погода!", при t ≤10º.
Решение.
t=input('Температура в градусах: ')
if t < 10:
s='Плохая погода!'
else:
s='Хорошая погода!'
print s
Начало каждой "ветви" программы обозначается символом ":". Условие записывается без скобок. В отличие от языка C++ окончание оператора if отсутствует как таковое. Следующий оператор начинается в строке без отступа. Поэтому нужно внимательно следить за отступами, так как иначе программа будет работать некорректно.
22
РАЗДЕЛ 3
Циклические алгоритмы
Циклические алгоритмы предоставляют возможность программирования повторяющихся действий.
В языке Python есть 2 основных циклических алгоритма: while и for.
Циклы WHILE
Инструкция while является самой универсальной конструкцией организации итераций в языке Python. Проще говоря, она продолжает выполнять блок инструкций (обычно с отступами) до тех пор, пока условное выражение продолжает возвращать истину. Она называется «циклом», потому что управление циклически возвращается к началу инструкции, пока условное выражение не вернет ложное значение. Как только в результате проверки будет получено ложное значение, управление будет передано первой инструкции, расположенной сразу же за вложенным блоком тела цикла while. В результате тело цикла продолжает выполняться снова и снова, пока условное выражение возвращает истинное выражение, а если условное выражение сразу вернет ложное значение, тело цикла никогда не будет выполнено.
Общий формат:
В своей наиболее сложной форме инструкция while состоит из строки заголовка с условным выражением, тела цикла, содержащего одну или более инструкций с отступами, и необязательной части else, которая выполняется, когда управление передается за пределы цикла без использования инструкции break. Интерпретатор продолжает вычислять условное выражение в строке заголовка и выполнять вложенные инструкции в теле цикла, пока условное выражение не вернет ложное значение:
While <условие>: #условное выражение
<тело цикла 1>
Else: #необязательная часть else
<тело цикла 2> #выполняется, если выход из цикла производится не
# инструкцией break
break, continue, pass
Pass
Инструкция pass не выполняет никаких действий и используется в случаях, когда синтаксис языка требует наличия инструкции, но никаких полезных действий в этой точке программы выполнить нельзя. Она часто
23
используется в качестве пустого тела составной инструкции. Грубо говоря, pass в мире инструкций – это то же, что None в мире объектов, – явное ничто. Инструкция pass используется например, для того, чтобы игнорировать исключение в инструкции try, или для определения пустых классов, реализующих объекты, которые ведут себя подобно структурам и записям в других языках. Иногда инструкция pass используется как заполнитель, вместо того, «что будет написано позднее».
Continue
Инструкция continue вызывает немедленный переход в начало цикла. Она иногда позволяет избежать использования вложенных инструкций. В языке Python нет инструкции «goto», но так как инструкция continue позволяет выполнять переходы внутри программы, большинство замечаний, касающихся удобочитаемости и простоты сопровождения, которые вы могли слышать в отношении инструкции «goto», применимы и к инструкции continue. Не злоупотребляйте использованием этой инструкции, особенно когда вы только начинаете работать с языком Python.
Break
Инструкция break вызывает немедленный выход из цикла. Так как программный код, следующий в цикле за этой инструкцией, не выполняется, если эта инструкция запущена, то ее также можно использовать, чтобы избежать вложения
Циклы FOR
Цикл for является универсальным итератором последовательностей в языке Python: он может выполнять обход элементов в любых упорядоченных объектах последовательностей. Инструкция for способна работать со строками, списками, кортежами, с другими встроенными объектами, поддерживающими возможность выполнения итераций, и с новыми объектами, которые создаются с помощью классов.
Общий формат:
Циклы for в языке Python начинаются со строки заголовка, где указывается переменная для присваивания (или – цель), а также объект, обход которого будет выполнен. Вслед за заголовком следует блок (обычно с отступами) инструкций, которые требуется выполнить:
For <переменная> in <объект> #связывает элементы объекта с переменной цикла
<тело цикла 1> #повторяющееся тело цикла: использует переменну
Else: #необязательная часть else
<тело цикла 2> #выполняется, если не попали на break
Когда интерпретатор выполняет цикл for, он поочередно, один за другим, присваивает элементы объекта последовательности переменной цикла и выполняет тело
24
цикла для каждого из них. Для обращения к текущему элементу последовательности в теле цикла обычно используется переменная цикла, как если бы это был курсор, шагающий от элемента к элементу.
В цикле for также используются инструкции break, continue, else.
Счетные циклы: while и range.
Функция range является по-настоящему универсальным инструментом, который может использоваться в самых разных ситуациях. Чаще всего она используется для генерации индексов в цикле for, но вы можете использовать ее везде, где необходимы с писки целых чисел. В Python 3.0 функция range возвращает итератор, который генерирует элементы по требованию, поэтому, чтобы отобразить результаты ее работы, мы должны обернуть вызов этой функции в вызов функции list:
List( range(5)), list( range(2, 5)), list( range(0, 10, 2))
([0, 1, 2, 3, 4], [2, 3, 4], [0, 2, 4, 6, 8])
Функция range с одним аргументом генерирует список целых чисел в диапазоне от нуля до указанного в аргументе значения, не включая его. Если функции передать два аргумента, первый будет рассматриваться как нижняя граница диапазона. Необязательный третий аргумент определяет шаг – в этом случае интерпретатор будет добавлять величину шага при вычислении каждого
последующего значения (по умолчанию шаг равен 1). Существует возможность воспроизводить последовательности чисел в диапазоне отрицательных значений и в порядке убывания:
List( range(-5, 5))
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
List( range(5, -5, -1))
[5, 4, 3, 2, 1, 0, -1, -2, -3, -4]
Такое использование функции range само по себе может быть полезным, однако чаще всего она используется в циклах for. Прежде всего, она обеспечивает простой способ повторить действие определенное число раз. Например, чтобы вывести три строки, можно использовать функцию range для создания соответствующего количества целых чисел – в версии 3.0 инструкция for автоматически извлекает все значения из итератора range, поэтому нам не потребовалось использовать функцию list:
for i in range(3):
... print(i, ‘Pythons’)
...
0Pythons
1Pythons
25
2 Pythons
Если вам действительно необходимо явно управлять логикой доступа к элементам, можно воспользоваться циклом while:
i = 0
while i < len(X):
print(X[i], end=’ ‘)
i+=1
Параллельный обход: zip и map
Встроенная функция zip позволяет использовать цикл for для обхода нескольких последовательностей параллельно. Функция zip принимает одну или несколько последовательностей в качестве аргументов и возвращает список кортежей, составленных из соответствующих элементов этих последовательностей. Например, предположим, что мы выполняем обработку двух списков:
L1 = [1,2,3,4]
L2 = [5,6,7,8]
Для объединения элементов этих списков можно использовать функцию zip, которая создаст список кортежей из пар элементов (подобно функции range, в версии 3.0 функция zip возвращает итерируемый объект,
поэтому, чтобы вывести все результаты, возвращаемые этой функцией, необходимо обернуть ее вызов вызовом функции list):
zip(L1, L2)
list(zip(L1, L2)) # Функция list необходима в 3.0, но не в 2.6
[(1, 5), (2, 6), (3, 7), (4, 8)]
Такой результат может пригодиться в самых разных ситуациях, но применительно к циклу for он обеспечивает возможность выполнения параллельных итераций:
for (x, y) in zip(L1, L2):
... print(x, y, ‘--’, x+y)
...
1 5 – 6
2 6 – 8
3 7 – 10
4 8 – 12
Здесь выполняется обход результата обращения к функции zip, то есть пар, составленных из элементов двух списков. Обратите внимание, что в этом цикле используется операция присваивания кортежей для получения элементов каждого кортежа, полученного от функции zip. На первой итерации она будет выглядеть,
26
как если бы была выполнена инструкция (x, y) = (1, 5). Благодаря этому мы можем сканировать оба списка L1 и L2 в одном цикле. Тот же эффект можно получить с помощью цикла while, в котором доступ к элементам производится вручную, но такой цикл будет сложнее в реализации и наверняка медленнее, чем прием, основанный на использовании for/zip. Функция zip на самом деле более универсальна, чем можно было бы представить на основе этого фрагмента. Например, она принимает последовательности любого типа (в действительности – любые итерируемые объекты, включая и файлы) и позволяет указывать более двух аргументов. При вызове с тремя аргументами, как показано в следующем примере, она конструирует список кортежей, состоящих из трех элементов, выбирая элементы из каждой последовательности с одним и тем же смещением (с технической точки зрения, из N аргументов функция zip создает N-мерный кортеж):
T1, T2, T3 = (1,2,3), (4,5,6), (7,8,9)
T3
(7, 8, 9)
list(zip(T1,T2,T3))
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
Длина списка, возвращаемого функцией zip, равна длине кратчайшей из последовательностей, если аргументы имеют разную длину.
Генерирование индексов и элементов: enumerate
Ранее мы рассматривали использование функции range для генерации индексов (смещений) элементов в строке вместо получения самих элементов с этими индексами.
Однако в некоторых программах необходимо получить и то, и другое: и элемент, и его индекс. Это можно выполнить с помощью функции enumerate:
S = ‘spam’
for (offset, item) in enumerate(S):
... print(item, ‘appears at offset’, offset)
...
s appears at offset 0
p appears at offset 1
a appears at offset 2
m appears at offset 3
27
РАЗДЕЛ 4
Обработка двумерных массивов (матриц)
Чтобы представить матрицу в языке Python можно использовать вложенные списки:
>> matrix = [ [1,2,3] , [4,5,6] , [7,8,9] ]
Список matrix содержит три элемента, каждый из которых также является списком, состоящим из трех элементов.
Обратившись к первому элементу списка matrix, мы получим вложенный список:
>> matrix[1]
4,5,6
Используя двойную индексацию, получим элемент вложенного списка. Первый индекс отвечает за вложенный список, второй – за элемент в этом списке:
>> matrix[1][2]
6
Генерация двумерных списков
Создадим матрицу размером n×n, заполненную нулями.
Чтобы получить n списков из n нулей, умножим список из n нулей на n:
>>n = 3
>>a = [ [ 0 ] * n ] * n
Теперь попробуем поменять какое-нибудь значение матрицы:
>> a[ 0 ][ 0 ] = 5
Но если мы выведем матрицу а на экран, то увидим, что изменились нулевые элементы во всех вложенных списках:
>> print(a)
[[5, 0, 0], [5, 0, 0], [5, 0, 0]]
Дело в том, что мы изначально создали список из n нулей, а потом создали список а как n ссылок на один и тот же список. Фактически мы создали не матрицу n×n, а строку из n элементов и скопировали ее n раз.
Чтобы действительно создать двумерный список, для каждого i от 0 до n-1 мы сгенерируем список из n элементов:
>> a = [ [ 0 ] * n for i in range(n) ]
Получили n независимых списков по n нулей в каждом.
28
Также можно использовать вложенные конструкции генератора списков:
>> a = [ [ 0 for i in range(n) ] for j in range(j) ]
Вывод на экран
Чтобы вывести двумерный список на экран, обычно используют два вложенных цикла for. Первый цикл пробегает по вложенным спискам, второй перебирает элементы внутри списка:
>>a = [ [1, 2, 3] , [4, 5, 6] , [7, 8, 9] ]
>>for i in a:
for j in i:
print( j , end = ' ' )
print( )
1 2 3
4 5 6
7 8 9
Для вывода по строкам можно использовать метод join:
>> for i in a:
print( ' '.join ( [ str( j ) for j in i ] ) )
Ввод с клавиатуры
Заполним массив n×m(элементы вводятся через пробел):
>>s = int( input( ) ) # вводим количество строк массива
>>a = [ ] # создаем пустой список
>>for i in range(s):
a.append( [ j for j in input( ).split( ) ] ) # добавляем в список по одному элементу
Или при помощи генератора:
>>s = int( input( ) )
>>a = [ [ j for j in input( ).split( ) ] for i in range(s) ]
Сапер
На вход подаются размеры поля для игры в сапер, количество мин и их координаты. Выводится поле игры, в котором указываются мины(*) и количество мин, находящихся рядом (если рядом с клеткой нет мин, то она обозначается точкой).
Пример входных данных
4 5 5
11
23
43
29