Файл: Учебник по информатике. Программирование на Python. Основы 1 Программирование на Python. Основы.pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 03.12.2023
Просмотров: 118
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Открытый учебник по информатике. Программирование на Python. Основы
40 s.strip([chars])
Возвращает строку – копию строки s, в которой удаляет все символы chars с концов строки s до первого несовпадения с последовательностью chars.
Для удаления ненужных символов справа или слева используются аналоги –
rstrip и lstrip соответтвенно.
Примеры.
'123abcdef46'.strip('1234567890') # 'abcdef'
'13323asv123'.rstrip('1234567890') # '13323asv'
'13323asv123'.lstrip('1234567890') # 'asv123'
s.lower()/s.upper()
Возвращает строку – копию строки s, в которой все символы преобразованы внижний/верхний регистр.
Примеры:
'fvbd123sDf'.lower() # 'fvbd123sdf'
'fvbd123sDf'.upper() # 'FVBD123SDF'
s.count(sub)
Возвращает число – количество непересекающихся подстрок sub в строке s.
Примеры:
'222mm2222'.count('22') # 3 '
22 2mm
2222
'
'123a12nb12'.count('12') # 3
'helloworld'.count('bye') # 0
Так же существует пара функций, которая позволяет работать с символами и кодировочной таблицей Unicode [13].
сhr(num)
Возвращает строку – символ по его номеру в кодировочной таблице
Unicode.
Примеры. chr(123) # '{' chr(32) # ' ' – пробел
ord(symbol)
Возвращает число – номер символа в кодировочной таблице Unicode.
Примеры. ord('a') # 97 ord(' ') # 32
Открытый учебник по информатике. Программирование на Python. Основы
41
ВАЖНО: сравнение символов происходит исходя из их позиции в таблице
Unicode. Больше номер – больше символ.
ВАЖНО!
При написании алгоритмов преобразующих строки необходимо помнить, что результаты работы методов нужно сохранять в качестве нового объекта.
Например, при переносе псевдокода из следующего задания на язык программирования Python, необходимо сохранять результат преобразования.
Также существует отдельный класс символов – графемы. Это специальные знаки, которые размещаются поверх других символов. Получаемые таким образом символы записываются как несколько символов.
Например, ḋ ̣ – это совмещенные символ ḋ и графема ̣. Для обработки таких символов функции ord и chr не применимы.
Пример.
Исполнитель Редактор получает на вход строку цифр и преобразует её.
Редактор может выполнять две команды, в обеих командах v и w обозначают цепочки символов.
1. заменить (v, w)
2. нашлось (v)
Первая команда заменяет в строке первое слева вхождение цепочки v на цепочку w. Если цепочки v в строке нет, эта команда не изменяет строку.
Вторая команда проверяет, встречается ли цепочка v в строке исполнителя
Редактор. На вход приведённой ниже программе поступает строка, состоящая из 107 букв Х. Какая строка получится после выполнения программы?
НАЧАЛО
ПОКА нашлось(XXX) или нашлось(ZYX) или нашлось(ZXX) заменить(XXX, ZZ) заменить(ZYX, X) заменить(ZXX, Y)
КОНЕЦ ПОКА
КОНЕЦ
Код на языке Python s = 'X'*107
while 'XXX' in s or 'ZYX' in s or 'ZXX' in s:
s = s.replace('XXX', 'ZZ', 1)
s = s.replace('ZYX', 'X', 1)
s = s.replace('ZXX', 'Y', 1)
print(s)
Открытый учебник по информатике. Программирование на Python. Основы
42
Экранирование
Нередко встречается необходимость ввести в строке спецсимвол, начиная от кавычки, которая используется для ограничения начала и конца строки, заканчивая символами которых нет на клавиатуре (перенос строки). Для таких случаев используется экранирование или escape-последовательности [14].
В качестве экранирующего символа используется обратный слеш «\».
Некоторые наиболее часто употребляемые escape-последовательности.
Escape-
последовательность
Значение
\newline
Обратный слеш игнорирует перенос строки
\\
Обратный слеш
\'
Одинарная кавычка
\"
Двойная кавычка
\n
Перевод на строку (LF)
\r
Возвращение каретки (CR)
\t
Горизонтальная табуляция (TAB)
\N{name}
Символ с именем name в Unicode
\uxxxx
Символ с 16-битным значением xxxx в Unicode
\Uxxxxxxxx
Символ с 32-битным значением xxxxxxxx в Unicode
Интересный факт.
Привычный нам разрыв строки на самом деле является комбинацией двух символов – «Возвращение каретки» и «Перевод на строку». При использовании escape-последовательности «\n» Python делает сразу два действия – переносит курсор на новую строку и передвигает каретку в начало строки. Исторически же это последовательность \r\n и пошла она с использования печатных машинок, при работе на которых для начала печати с новой строки передвигали печатающий вал, который при передвижении до левого края прокручивался и устанавливал бумагу в положение, соответствующее новой строке.
Открытый учебник по информатике. Программирование на Python. Основы
43
Символ \r можно использовать, чтобы печатать поверх выведенного текста, заменяя уже выведенные символы на новые.
Пример (time.sleep(n) – функция, осуществляющая задержку n секунд). from time import sleep print("Loading 0%...", end='') sleep(1) print("\rLoading 1%...", end='')
Одной из частых проблем при работе с экранированными символами является открытие файла по абсолютному адресу, где адрес представлен, как строка
'имя_диска:\путь\до\файла.txt'. Дело в том, что такая строка будет считать, что экранированы символы «п», «д» и «ф».
Чтобы этого избежать, необходимо либо продублировать символ обратного слеша 'имя_диска:\\путь\\до\\файла.txt', либо дописать префикс r (от англ. raw
– необработанный) перед строкой r'имя_диска:\путь\до\файла.txt'.
При использовании префикса r стоит помнить, что строка не может оканчиваться нечетным количеством обратных слешей, так как в таком случае последний обратный слеш будет экранировать кавычку, закрывающую строку.
Либо можно заменить все обратные слеши на прямые, например,
'имя_диска:/путь/до/файла.txt'
Преобразование строки в список/кортеж
Также строку можно преобразовать в список или кортеж отдельных символов.
>>>s = '123455'
>>>list(s)
['1', '2', '3', '4', '5', '5']
>>>s = '112345'
>>>tuple(s)
('1', '1', '2', '3', '4', '5')
Открытый учебник по информатике. Программирование на Python. Основы
44
Форматирование чисел при выводе
f-строки – очень удобный способ форматирования строк, который позволяет удобно добавлять в строку значения переменных и форматировать их.
Поддержка f-строк начинается с версии Python 3.6, выпущенной в 2015 году, поэтому шанс встретить версию интерпретатора без поддержки f-строк крайне невелик.
Рассмотрим лишь некоторые особенности использования f-строк.
Количество знаков до и после запятой f'{x[:[0][count].[precision]}'
На 0 указывается, если необходимо дополнить выводимое число нулями до количества count. Значение precision отвечает за количество знаков после запятой.
Примеры.
>>>x = 3/7
>>>f'{x:.5}'
'0.42857'
>>>f'{x:10.4}'
' 0.4286'
>>>f'{x:08.3}'
'0000.429'
Перевод целого числа в 2, 8 и 16 системы счисления. f'{x[:[[0]count]type]}'
На месте count указывается необходимое количество символов, которое должно занимать выводимое значение. 0 указывается в случае, если нужно вывести незначащие нули до длины count. В качестве type может стоять одно из следующих значений:
Тип
Значение
b
Двоичный формат
d
Десятичный формат
o
Восьмеричный формат
x
Шестнадцатеричный формат (нижний регистр)
X
Шестнадцатеричный формат (верхний регистр)
Открытый учебник по информатике. Программирование на Python. Основы
45
Говоря иначе доступны следующие форматы: f'{x}'
Выводит десятичное число без форматирования.
>>> f'{123}'
'123’ f'{x:
Выводит число в указанном формате.
>>> f'{123:b}'
'1111011'
>>> f'{123:X}'
'7B'
f'{x:
Выводит число в формате type длиной count символов.
>>> f'{12:6b}'
' 1100'
>>> f'{123:5X}'
' 7B' f'{x:0
Выводит число в формате type из count символов, в котором при необходимости дописаны ведущие нули.
>>> f'{12:60b}'
'001100'
>>> f'{123:50X}'
'0007B'
Если не указывается формат вывода type, то по умолчанию принимается десятичный.
Если count или type являются вычислимыми значениями или значениями переменных, то переменная или выражение берутся в фигурные скобки.
>>> x = 15
>>> count = 20
>>> f'{x:0{count}}'
'00000000000000000015'
Открытый учебник по информатике. Программирование на Python. Основы
46
Операторы переопределения
Так как последовательности поддерживают операторы + и *, они также поддерживают и операции += и *=.
При работе со списками (и другими объектами изменяемого типа) важно понимать, что хоть ссылка на объект и остается прежней, эти операторы являются операторами присваивания.
Важность этого поведения мы можем увидеть при работе с кортежем изменяемых объектов.
Пример. a = ([1, 2], [2, 3])
В этой строке мы создали кортеж, который хранит две ссылки на объекты списков. Данные ссылки нельзя менять, то есть пара объектов должна всегда быть одними и теми же объектами. Попробуем дополнить любой из объектов. a[0] += [4, 5]
Интерпретатор вернет ошибку
«TypeError: 'tuple' object does not support item assignment»
«Ошибка типа: объект ‘кортеж’ не поддерживает операцию присваивания
элементов».
Однако, если мы обратимся к методам списка, которые его расширяют: a[0].append(3) a[0].extend([4, 5])
То такой ошибки не будет, потому что нет ошибки присваивания и мы обращаемся к методу объекта, что не запрещено для объектов внутри кортежа.
Для иллюстрации оператор += можно заменить на эквивалентную запись с использование функции iadd модуля operator. import operator x = [1, 2]
# Эквивалентная запись для x += [4, 5] x = operator.iadd(a, [4, 5])
Объект x будет иметь прежний id. Однако, исходя из того, как работает оператор присваивания, мы понимаем, что operator.iadd возвращает ссылку на преобразованный объект x, что считывается интерпретатором как переприсваивание или переопределение объекта, на который ссылается переменная.
Открытый учебник по информатике. Программирование на Python. Основы
47
Итераторы
При работе с итераторами можно выделить две базовые сущности – итерируемый объект (iterable object) и собственно итератор (iterator).
Если коротко и несколько упрощенно, то отличия следующие. Итерируемый объект – это такой объект, элементы которого можно перебрать. Например, итерируемым объектом может быть любой объект-последовательность.
Итератор – это специальный объект, который перебирает элементы итерируемого объекта.
Чтобы из итерируемого объекта создать итератор, необходимо передать его в функцию iter(). После чего можно получать значения из итерируемого объекта с помощью функции next() подавая ей на вход итератор с предыдущего шага.
Пример.
>>> it = iter('abc')
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
File "
", line 1, in
StopIteration
В рассмотренном примере можно заметить, что функция next() последовательно вывела все элементы строки 'abc' и при следующем обращении вернула исключение StopIteration.
И в этом состоит одно очень важное отличие итераторов от итерируемых объектов. Итератор может обратиться к каждому элементу только один раз в порядке слева направо. При работе же с итерируемым объектом мы всегда можем обратиться к элементу или проверить его наличие.
Открытый учебник по информатике. Программирование на Python. Основы
48
Рассмотрим данное утверждение на примере работы оператора in.
Оператор in для последовательностей (итерируемых объектов) и итераторов работает схожим образом – проверяет последовательно элементы слева направо и, если находит элемент с искомым значением, возвращает True, иначе False.
Пример.
>>> obj = [1, 2, 3, 4, 5]
>>> it = iter(obj)
>>> 3 in obj
True
>>> 3 in it
True
Видим идентичные результаты. Значит ли это, что итератор и итерируемый объект равнозначны? Хочется ответить, что да. И в этом заключается очень частая ошибка тех, кто забывает результат в виде итератора преобразовать в последовательность.
При повторном таком обращении мы увидим отличные поведения для итератора и списка.
>>> 3 in obj
True
>>> 3 in it
False
В чем отличие первого вызова от второго? Как было сказано ранее, оператор
in обрабатывает элементы слева направо. Условно работу можно рассмотреть как пошаговую следующим образом.
№ шага Список
Итератор
Результат
сравнения
1 obj[0] == 3 # 1 next(it) == 3 # 1
False
2 obj[1] == 3 # 2 next(it) == 3 # 2
False
3 obj[2] == 3 # 3 next(it) == 3 # 3
True !!!
То есть после первого срабатывания оператора in список в obj не изменился, однако теперь next(it) вернет нам 4. Поэтому при следующем вызове next(it) итератор продолжит с места, где закончил в прошлый раз – на значении 4.
Тут же важно отметить, что итератор не хранит все значения, которые возвращаются путём вызова функции next(), он получает их по мере обращения. То есть запоминает место, где закончил вывод и при следующем обращении к next() возвращает следующий элемент.
При работе на python мы будем часто обращаться к функциям и методам, которые возвращают именно итератор. Поэтому это отличие для нас очень значимое.
Открытый учебник по информатике. Программирование на Python. Основы
49
Функция map
Функция, которую используют все, но не все задумываются, как она работает. map(function, iterableObject[,io2[,io3[, ...])
Функция map возвращает итератор, каждый элемент которого является результатом применения функции function к элементу итерируемого объекта
iterableObject или к параллельным наборам перечисленных через запятую итерируемых объектов. Во втором случае перебираемые группы значений передаются как отдельные значения (подробнее в одной из следующих глав).
Также отдельно следует упомянуть важную особенность работы с результатами работы функции map.
Если мы присвоим переменной результат map, то переменная будет ссылаться на итератор! Поэтому для возвращения всех обработанных функцией map элементов необходимо преобразовать результат в одну из допустимых последовательностей, например, кортеж.
Пример.
>>> map(str, [123,321,1111,101])
Открытый учебник по информатике. Программирование на Python. Основы
50
Вариант 1:
1. Мы уже знаем, что для разбивки строки по пробелу есть функция
s.split(), которая по умолчанию разбивает строку по пробельным символам. str_values = input().split()
2. Теперь переменным x, y, z необходимо присвоить числовые значения, соответствующие введенным строковым значениям.
Способ 1. x = int(str_values[0]) y = int(str_values[1]) z = int(str_values[2])
Способ 2. int_iter = map(int, str_values) x, y, z = next(int_iter), next(int_iter), next(int_iter)
Вариант 2: x, y, z = map(int, input().split())
Вариант №2 является сокращенной записью алгоритма из варианта №1.
Однако если у нас будет введено больше значений через пробел, то вариант
№2 вернет ошибку. Если меньше, то не сработает и первый.
Поэтому вариант, который работает правильно, будет такой. str_values = input().split() if len(str_values) == 3: x, y, z = map(int, str_values)
На ЕГЭ таких проверок делать не надо, однако при написании более сложных алгоритмов необходимо учитывать возможность некорректного ввода.