Учебник по информатике. Программирование на Python. Основы 1 Программирование на Python. Основы
Скачать 1.27 Mb.
|
Последовательности и итераторы Последовательности В Python есть так называемые типы-последовательности (Sequences). Последовательность – общий термин, который предполагает упорядоченный набор данных. Говоря иначе, элементы в объекте-последовательности будут расположены в том же порядке, в котором будут добавлены, либо объявлены (в зависимости от того, изменяемая последовательность или нет). К последовательностям относят типы: str, list, tuple, bytes, bytesarray и range. Обращение к элементам объекта последовательности происходит путем указания номера (индекса) элемента в последовательности. При этом элементы последовательности нумеруются от первого к последнему, начиная с нуля, или от последнего к первому в обратном порядке, начиная с -1. Так, если последовательность S содержит 5 элементов, то обращение к S 3 эквивалентно обращению к S- 2 (рис.1). Рисунок 1. Прямая и обратная нумерация в Python Для обращения к элементу последовательности по индексу используется синтаксическая конструкция s[index], где s – последовательность, к элементу которой необходимо обратиться, index – индекс элемента в прямой или обратной нумерации. При попытке выхода за границы последовательности (указание несуществующего индекса), интерпретатор вернет ошибку «IndexError: выходит за допустимый диапазон». ВАЖНО: допустимые индексы элементов последовательности всегда находятся в диапазоне [-len(seq); len(seq)-1], где len(seq) – количество элементов последовательности Методы работы с каждым из перечисленных выше типов мы разберем подробнее чуть ниже. Сейчас же нам важно понимать, как обозначаются (инициализируются) значения для данных типов. Открытый учебник по информатике. Программирование на Python. Основы 28 Тип Пример Описание Строка (str) s = '12345abcde' Строка из 10 символов. s[0] – '1', s[1] – '2', …, s[9] – 'e'. Кортеж (tuple) s = (1, 2, '123', 5) Неизменяемая последовательность из 4 объектов s[0] – 1, s[1] – 2, s[2] – '123', s[3] – 5. Список (list) s = [5, 10, 'asd'] Изменяемая последовательность из 3 объектов s[0] – 5, s[1] – 10, s[2] – 'asd'. Стоит заметить, что для создания пустой последовательности необходимо оставить незаполненным пространство между границами последовательности: • s = '' для строки, • t = () для кортежа, • l = [] для списка. Также надо помнить, что кортеж из одного элемента определяется несколько неочевидным образом. Так как при отсутствии нескольких значений в круглых скобках, записанное значение интерпретируется, как отдельный объект – результат выполнения операций в скобках. Например, при записи x = (3) получим объект типа int со значением 3. То есть такие скобки считаются скобочными группами в выражении, так же как в выражении x = (25 – y) * 5. Ведь если бы это было не так, то подвыражение (25 – y) воспринималось бы как кортеж, что привело бы к неправильному результату при вычислении данного выражения. Поэтому для формирования кортежа из одного элемента кортеж записывают как одноэлементный кортеж (singleton tuple) с помощью запятой, после которой не указывается следующий элемент. t = (1,) t = 1, Строго говоря, также мы можем не указывать последний элемент и при инициализации списка. Однако, обычно в этом нет необходимости. Открытый учебник по информатике. Программирование на Python. Основы 29 Общие функции, операторы и методы для последовательностей Последовательности поддерживают ряд общих методов и операторов [10]. Метод Обращение Пример Количество элементов len(seq) len('1234') #4 len([1,4,8]) #3 Конкатенация (сложение) seq1 + seq2 'asd'+'123' #'asd123' [5]+[1,3] #[5,1,3] Повторение N раз seq*N N*seq 'a'*4 # 'aaaa' 2*[4, 2]#[4, 2, 4, 2] Проверка вхождения value value in seq '4' in '123234'#True '0' in '123' #False Проверка НЕвхождения value value not in seq '1' not in '22'#True '2' not in '22'#False Количество вхождений value seq.count(value) '12311'.count('1') #3 Индекс первого (левого) элемента value seq.index(value) '12511'.index('5') #2 Максимальный элемент max(seq) max([5,2,10,2]) #10 max('12345asdfw')#'w' Минимальный элемент min(seq) min([5,2,10,2]) #2 min('12345asdfw')#'1' Сортировка элементов sorted(seq, reverse=True/False) sorted('bac') # ['a', 'b', 'c'] Функция sorted всегда возвращает список элементов последовательности, поданной в качестве аргумента. Важно, что при операциях поиска (count, index, in, not in) тип элемента value был совместим с объектом последовательности. Например, если мы производим поиск в строке, то нельзя в качестве искомого значения использовать любые значения, кроме строк. При вызове методы index, если элемент отсутствует в последовательности, интерпретатор вернет ошибку «ValueError: «Ошибка значения: значение отсутствует в последовательности». Методы count, index и операторы in, not in для строки позволяют искать не только единичные символы, но и подстроки. Открытый учебник по информатике. Программирование на Python. Основы 30 Примеры '15243'.index('2') # 2 '15243'.index('43') # 3 '12112'.count('1') # 3 '12112'.count('12') # 2 [1, 2, 3].index(2) # 1 [1, 2, 3].index([2, 3]) # ValueError [1, 2, 3].count(3) # 1 [1, 2, 3].count([2, 3]) # 0 В примере [1, 2, 3].index([2, 3]) получаем ValueError так как в списке нет ЭЛЕМЕНТА, содержащего список [2, 3]. В отличии от следующей записи [1, 2, [3, 4]].index([3, 4]) # 2 Сравнение последовательностей В общем случае последовательности сравниваются поэлементно. Сравнение допустимо только между последовательностями одного типа. При сравнении на равенство между различными типами последовательностей результатом будет ложь. При попытке сравнения порядка – ошибка несовместимости типов. >>>a, b, c = ['1', '2'], ('1', '2'), '12' >>>a == b False >>>b == c False >>>a > b TypeError: '>' not supported between instances of 'list' and 'tuple' Признак равенства – все элементы S соответствуют элементам F или s i = f i и f j = s j для всех допустимых i и j. Говоря иначе последовательности F и S должны быть одинаковой длины и элемент, стоящий на позиции i в F, должен быть равен элементу на i-той позиции S. Последовательности сравниваются лексикографически – слева направо. То есть операция сравнения применяется последовательно к элементам последовательности, начиная с самого левого (нулевого) элемента. И происходит до тех пор, пока либо не дойдет до конца обоих последовательностей (в случае равных последовательностей), либо не найдет отличия в одном из элементов. Если одна из последовательностей является началом другой, то последовательность большей длины считается последовательностью с бóльшим значением. Пример. Открытый учебник по информатике. Программирование на Python. Основы 31 '1234' < '12057' Элемент левой последовательности Элемент правой последовательности Результат сравнения Шаг 1 '1' '1' == Шаг 2 '2' '2' == Шаг 3 '3' '0' > Первая пара отличающихся элементов последовательностей – символы '3' и '0'. Данные элементы противоречат проверяемому условию ('3' > '0'), следовательно, результат сравнения равен False. Важно! Последовательности сравнимы только в том случае, если между соответствующими элементами определены операции сравнения. Если же это не так, то интерпретатор вернет ошибку «TypeError: between instances of Это же замечание применимо для функции сортировки – sorted может отсортировать только такую последовательность, все элементы которой могут быть сравнимы между собой. Пример. >>>a = [1, 2, 3] >>>b = [1, 2, '3'] >>>a > b TypeError: '>' not supported between instances of 'int' and 'str' Операция сравнения возвращается ошибку, так как элементы a[2] и b[2] имеют разные типы, операция «>» над которыми не определена. Открытый учебник по информатике. Программирование на Python. Основы 32 Срезы Срезом называется подпоследовательность последовательности от элемента start до элемента finish с шагом step. Причем элемент с индексом start включается в срез, элемент с индексом finish – не включается. Результатом взятия среза является новый объект того же типа, что и последовательность из которой извлекается срез. Значение шага step – целое число, не равное 0. seq[start:finish:step] Каждый из параметров среза является необязательным. • при неуказанном параметре start – значение считается 0 при положительном step и -1 при отрицательном; • при неуказанном параметре finish – последовательность обрабатывается до конца при положительном step, и до начала при отрицательном; • значение step по умолчанию равно 1. Срез будет непустым, при: • положительном шаге и положении индекса start левее индекса finish, • отрицательном шаге и положении индекса start правее индекса finish. Во всех остальных случаях срез будет пустым. Примеры (помним, что элементы нумеруются с нуля). 'abcdefgh'[2:6:3] == 'cf ' # 2 и 5 элементы 'abcdefgh'[5:1:-1] == 'fedc ' # 5, 4, 3, 2 элементы 'abcdefgh'[-4:6] == 'ef ' # 5, 6 или -4, -5 'abcdefgh'[::-1] == 'hgfedcba '# задом-наперед Можно заметить, что при указании индексов в разном направлении нумерации в рамках одного среза срез берется от указанного слева ЭЛЕМЕНТА до указанного справа ЭЛЕМЕНТА и не продолжается в обратном направлении. Например, срез '012345678'[-5:8:2] не будет перебирать значения индексов в диапазоне [-5; 8] с шагом 2 – [-5, -3, -1, 1, 3, 5, 7] . Вместо этого будет обработана последовательность между элементами '012345678'[-5] = '4' и '012345678'[8] = '7' . Соответственно, в срез попадут только выделенные символы '012345678' с шагом 2. В результате чего получим строку '46' (см.рис.2). Открытый учебник по информатике. Программирование на Python. Основы 33 Рисунок 2. Срез при указании индексов разными способами индексирования Кортежи Самый простой тип последовательностей. С ним буквально нельзя делать ничего, кроме общих операций из таблицы выше. Кортеж – последовательность объектов, которая определена единожды. То есть мы не можем переопределять уже добавленный в кортеж объект. При сложении двух кортежей получается новый объект, содержащий элементы двух кортежей в добавленном порядке. Операция += для кортежа работает аналогично записи tup = tup + add_tup , так как функция расширения объекта не применима к объектам неизменяемого типа данных. Другими словами создается НОВЫЙ объект, ссылкой на который будет переопределенная переменная. Аналогично работает оператор *=. Кортежи очень полезны, когда нам нужно обработать массив данных при этом не изменив его. Открытый учебник по информатике. Программирование на Python. Основы 34 Списки Списки – наиболее часто используемый тип для хранения последовательностей. Он весьма удобен, так как позволяет сохранить как отдельные значения, так и сложные объекты в качестве своих элементов. Обычно списки используют для хранения однотипных данных. Такой подход позволяет писать быстрые и удобные алгоритмы для обработки хранимых значений. Поддерживаемые операторы Операторы изменения объекта lst += lst2 и lst *= N расширяют объект при этом не меняя ссылку на него. Операторы проверки вхождения элемента в последовательность val in lst и val not in lst определяют входит или не входит элемент со значением val в список lst. Методы работы со списками s.append(value)/s.extend(values) Методы расширения списка. - append добавляет ОДИН элемент value в конец списка s. - extend присоединяет список values в конец списка s. Для добавления одного элемента рекомендуется использовать append, для добавления нескольких – extend. Примеры. s = [1, 2, 3] s.append(5) # [1, 2, 3, 5] s.extend([2,4,6]) # [1, 2, 3, 5, 2, 4, 6] s.remove(value) Удаляет первое вхождение значения value из списка. Если в списке нет искомого значения, будет возвращена ошибка «ValueError: list.remove(x): x not in list» или «Ошибка значения: list.remove(x): x отсутствует в списке». Примеры. s = [1, 2, 3] s.remove(2) # [1, 3] s.remove(10) # ValueError Открытый учебник по информатике. Программирование на Python. Основы 35 s.copy() Метод возвращающий копию объекта. Пример. s = [1, 2, 6, 10] sc = s.copy() # [1, 2, 6, 10] ВАЖНО: возвращается неглубокая копия, то есть копируются ссылки на объекты оригинального списка. Поэтому, если в качестве элемента оригинального списка было значение изменяемого типа, то вернется ссылка на этот же объект. Пример. # пример работы с изменением объекта s = [1, [1, 2], 3, 4] sc = s.copy() sc[1] += [2, 4] # меняем sc print(s) # [1, [1, 2, 2, 4], 3, 4] – s меняется тоже Для создания полного дубликата (глубокое копирование) можно воспользоваться методом deepcopy() из библиотеки copy. s.sort(reverse=True/False) Метод, сортирующий элементы в списке s. Также может производить сортировку в обратном порядке (при указании аргумента reverse=True). С методами настраиваемых сортировок мы разберемся в одной из следующих глав. ВАЖНО: изменяет список s в отличии от функции sorted для последовательностей. Примеры. s = [1, 3, 2, 10, 6, 2] s.sort() # s = [1, 2, 2, 3, 6, 10] s.sort(reverse=True) # s = [10, 6, 3, 2, 2, 1] s.reverse() «Переворот» списка, расположение элементов в обратном порядке. Результат аналогичен взятию среза s[::-1] за тем исключением, что при использовании s.reverse() объект останется прежним. Пример. s = [1, 5, 2, 8] s.reverse() # [8, 2, 5, 1] Открытый учебник по информатике. Программирование на Python. Основы 36 s.insert(index, value) Вставка значения value на позицию index. Все элементы, которые имели позицию бóльшую или равную значению index, сдвигаются на 1 вправо (индекс увеличивается на 1). ВАЖНО: если указать значение index, выходящее за допустимый диапазон индексов для изменяемого списка, то в случае значения index, меньше допустимой левой границы, элемент будет добавлен в начало списка, в случае значения index больше длины последовательности – в конец. Примеры. s = [1, 2, 3] s.insert(1, 10) # [1, 10, 2, 3] s.insert(0, 11) # [11, 1, 10, 2, 3] s.insert(-100, 8) # [8, 11, 1, 10, 2, 3] s.insert(20, 22) # [8, 11, 1, 10, 2, 3, 22] s.pop(index) Удаляет элемент с индексом index и возвращает его в качестве результата. В случае указания недопустимого индекса возвращается ошибка «IndexError: pop index out of range» или «Ошибка индекса: указанный индекс удаляемого элемента выходит за допустимый диапазон». Если не указывать значение index, будет удален последний элемент списка. Примеры. s = [1, 2, 3, 4, 5] x = s.pop(3) # s = [1, 2, 3, 5], x = 4 s.pop(100) # IndexError s = [1, 2, 3, 4, 5] y = s.pop() # s = [1, 2, 3, 4], y = 5 Открытый учебник по информатике. Программирование на Python. Основы 37 Строки Необходимо понимать, что строковый тип данных неизменяемый. Поэтому всегда, когда мы получаем строку отличную от обрабатываемой, создается новый объект. Также нужно понимать, что отдельный символ также является строкой. >>>s[i] == s[i:i+1] True Поддерживаемые операторы Операторы изменения объекта s += sub и s *= N работают аналогично записям s = s + sub и s = s * N соответственно, создавая новый объект и связывая старое имя переменной с созданным объектом. Операторы проверки вхождения элемента в последовательность sub in s и sub not in s определяют является/не является ли строка sub подстрокой (частью) s. Методы работы со строками Строковый тип данных поддерживает достаточно большое количество методов. В контексте данного учебника мы не будем рассматривать их все, при желании с полной документацией можно ознакомиться в источнике [10]. Все указанные методы НЕ ИЗМЕНЯЮТ объект строки для которого вызваны. s.find(sub[, start[, end]]) s.index(sub[, start[, end]]) Возвращает число – индекс первого вхождения слева подстроки sub, начиная с индекса start и заканчивая индексом end. Аргументы start и end – необязательные. Для поиска справа используются аналоги – rindex, rfind. Разница index и find: • если find не находит совпадение, результат равен -1, • если index не находит совпадение – интерпретатор возвращает ошибку. Примеры. 'adbefb'.find('bef') # 2 'adbefb'.index('bef') # 2 'adbefb'.index('cef') # Error 'adbefb'.find('aaa') # -1 Открытый учебник по информатике. Программирование на Python. Основы 38 s.isdecimal() Возвращает логическое значение – True, если все символы являются десятичными цифрами, False в обратном случае. Стоит заметить, что это символы, которые входят в категорию «Number, Decimal Digits, Nd» таблицы Unicode [11]. Примеры. '12345'.isdecimal() # True '123asd321'.isdecimal() # False s. |