Математический анализ. 3е издание
Скачать 4.86 Mb.
|
188 Глава 7. Строки В языке Python строки символов Юникода можно записывать, добав ляя символ U (в верхнем или нижнем регистре) перед открывающей кавычкой: >>> u'spam' u'spam' Формально с помощью этого синтаксиса создается объект строки сим волов Юникода, который является самостоятельным типом данных, отличным от обычного строкового типа. Однако Python позволяет лег ко смешивать в выражениях строки символов Юникода и обычные строки, преобразуя последние до строк символов Юникода при вычис лении результата (подробнее об операции конкатенации рассказывает ся в следующем разделе): >>> 'ni' + u'spam' # Смешивание строк различных типов u'nispam' На практике строки символов Юникода поддерживают все обычные операции над строками, которые встретятся вам в следующем разделе, поэтому для вашего программного кода различия в типах играют несу щественную роль. Подобно обычным строкам, строки символов Юни кода могут объединяться, из них можно извлекать отдельные символы и подстроки, производить поиск по шаблону с помощью модуля re и т. д., и эти строки также являются неизменяемыми. Даже если у вас возникнет необходимость явно выполнить преобразо вание между этими двумя типами, вы можете использовать встроен ную функцию unicode: >>> str(u'spam') # Из Юникода в обычную строку 'spam' >>> unicode('spam') # Из обычной строки в Юникод u'spam' Поскольку кодировка Юникод предназначена для работы с многобай товыми символами, вы также можете использовать экранированные последовательности \u и \U для представления символов Юникода в виде числовых значений, размер которых превышает 8 битов: >>> u'ab\x20cd' # 8битовые/1байтовые символы u'ab cd' >>> u'ab\u0020cd' # 2байтовые символы u'ab cd' >>> u'ab\U00000020cd' # 4байтовые символы u'ab cd' Первая из этих инструкций встраивает числовой код символа пробела, который в шестнадцатеричной записи имеет вид x20. Вторая и третья инструкции делают то же самое, но используют 2байтовое и 4байтовое представление в виде экранированных последовательностей. Даже если вы полагаете, что вам не понадобятся символы Юникода, вам, возможно, хотя бы неявно придется использовать их. Поскольку Литералы строк 189 некоторые программные интерфейсы (например, COM API в Windows и некоторые синтаксические анализаторы XML) представляют текст в кодировке Юникод, это может повлечь за собой необходимость выпол нять преобразование между обычной кодировкой и кодировкой Юни код при передаче текста таким API или при получении результатов. В большинстве случаев интерпретатор Python рассматривает эти два типа строк как взаимозаменяемые, поэтому присутствие строк симво лов Юникода часто проходит незамеченным для вашего программного кода – в большинстве случаев вы можете просто игнорировать тот факт, что текст передается между программными компонентами в ви де объектов строк символов Юникода, и использовать обычные стро ковые операции. Поддержка Юникода – это полезное встроенное дополнение в языке Py thon, поэтому данные в кодировке Юникод легко обрабатываются в сце нариях. Безусловно, о Юникоде можно рассказать больше. Например: • Объекты строк Юникода предоставляют метод, выполняющий пре образования строки символов Юникода в обычную строку 8бито вых символов с использованием указанной кодировки. • Встроенная функция unicode и модуль codecs поддерживают зареги стрированные «кодеки» («codec», от слов «COders» и «DECoders») Юникода. • Функция open из модуля codec позволяет обрабатывать текстовые файлы в кодировке Юникод, где каждый символ может быть пред ставлен более чем одним байтом. • Модуль unicodedata предоставляет доступ к базе данных символов Юникода. • Модуль sys включает функции для получения и изменения схемы кодирования Юникод (по умолчанию обычно используется ASCII). • Допускается комбинировать форматы представления неформатиро ванных строк и строк символов Юникода (например, ur'a\b\c'). Поскольку тема использования кодировки Юникод является достаточ но сложной, и это не самый распространенный инструмент, мы не бу дем обсуждать ее далее в этой вводной книге. Дополнительные сведе ния о Юникоде вы найдете в стандартном руководстве по языку Python. В Python 3.0 строковый тип претерпит некоторые изменения: в версии 3.0 текущий тип str всегда будет представлять строки символов Юникода, а также появится новый тип – «байты», из меняемая последовательность малых целых чисел, удобная для представления коротких строк символов. Некоторые операции чтения из файла будут возвращать байты вместо типа str (напри мер, при чтении двоичных файлов). Однако все это пока только в планах, поэтому подробности вам следует искать в примечани ях к выпуску 3.0. 190 Глава 7. Строки Строки в действии Как только с помощью литеральных выражений, с которыми мы толь ко что познакомились, строка будет создана, вам наверняка потребует ся выполнять какиелибо операции с ее участием. В этом и в следую щих двух разделах демонстрируются основы работы со строками, фор матирование и методы – первая линия инструментальных средств об работки текста в языке Python. Базовые операции Давайте запустим интерактивный сеанс работы с интерпретатором Py thon, чтобы проиллюстрировать базовые операции над строками, ко торые были перечислены в табл. 7.1. Строки можно объединять с по мощью оператора конкатенации + и дублировать с помощью оператора повторения *: % python >>> len('abc') # Длина: число элементов 3 >>> 'abc' + 'def' # Конкатенация: новая строка 'abcdef' >>> 'Ni!' * 4 # Повторение: подобно "Ni!" + "Ni!" + ... 'Ni!Ni!Ni!Ni!' Формально операция сложения двух строковых объектов создает но вый строковый объект, объединяющий содержимое операндов. Опера ция повторения напоминает многократное сложение строки с самой собой. В обоих случаях Python позволяет создавать строки произволь ного размера – нет никакой необходимости предварительно объявлять что бы то ни было, включая размеры структур данных. 1 Встроенная функция len возвращает длину строки (или любого другого объекта, который имеет длину). Операция повторения на первый взгляд выглядит несколько странно, но она очень удобна в очень широком диапазоне применений. Напри 1 В отличие от массивов символов в языке C, при работе со строками в языке Python вам не нужно выделять или управлять памятью массивов – вы про сто создаете объекты строк, когда в этом возникает необходимость, и позво ляете интерпретатору самому управлять памятью, выделяемой для этих объектов. Как уже говорилось в предыдущей главе, Python автоматически освобождает память, занятую ненужными объектами, используя страте гию сборки мусора, основанную на подсчете количества ссылок. Каждый объект следит за количеством имен, структур данных и другими компонен тами, которые ссылаются на него. Когда количество ссылок уменьшается до нуля, интерпретатор освобождает память, занятую объектом. Это озна чает, что интерпретатору не требуется останавливаться и просматривать всю память в поисках неиспользуемого пространства (дополнительный компонент сборки мусора собирает также циклические объекты). Строки в действии 191 мер, чтобы вывести строку из 80 символов дефиса, можно самому со считать до 80, а можно возложить эту работу на плечи интерпретатора: >>> print ' ...много дефисов... ' # 80 дефисов, сложный способ >>> print ' '*80 # 80 дефисов, простой способ Обратите внимание: здесь работает механизм перегрузки операторов: мы используем те же самые операторы + и *, которые используются для выполнения операций сложения и умножения с числами. Интер претатор выполняет требуемую операцию, потому что ему известны типы объектов, к которым применяются операции сложения и умно жения. Но будьте внимательны: правила не так либеральны, как мо жет показаться. Например, интерпретатор не позволяет смешивать строки и числа в выражениях сложения: 'abc' + 9 вызовет ошибку вме сто того, чтобы автоматически преобразовать число 9 в строку. Как показано в последней строке табл. 7.1, допускается выполнять об ход элементов строки в цикле, используя инструкцию for, и проверять вхождение подстроки в строку с помощью оператора выражения in, который, по сути, выполняет операцию поиска: >>> myjob = "hacker" >>> for c in myjob: print c, # Обход элементов строки в цикле h a c k e r >>> "k" in myjob # Найдено True >>> "z" in myjob # Не найдено False Оператор цикла for присваивает переменной очередной элемент после довательности (в данном случае – строки) и для каждого элемента вы полняет одну или более инструкций. В результате переменная c пре вращается в своего рода курсор, который постепенно перемещается по строке. Далее в этой книге мы подробнее рассмотрим средства выпол нения итераций, подобных этим. Доступ по индексам и извлечение подстроки Так как строки определены как упорядоченные коллекции символов, мы можем обращаться к элементам строк по номерам позиций. В язы ке Python символы извлекаются из строк с помощью операции индек+ сирования – указанием числового смещения требуемого компонента в квадратных скобках после имени строки. В результате операции вы получаете строку, состоящую из одного символа, находящегося в ука занной позиции. Как и в языке C, в языке Python смещения символов в строках начина ют исчисляться с 0, а последний символ в строке имеет смещение на единицу меньше длины строки. Однако, в отличие от C, Python также позволяет извлекать элементы последовательностей, таких как строки, 192 Глава 7. Строки используя отрицательные смещения. Технически отрицательное смещение складывается с длиной строки, чтобы получить положи тельное смещение. Отрицательные смещения можно также предста вить себе как отсчет символов с конца строки. Например: >>> S = 'spam' >>> S[0], S[ 2] # Индексация от начала или от конца ('s', 'a') >>> S[1:3], S[1:], S[: 1] # Получение среза: извлечение подстроки ('pa', 'pam', 'spa') В первой строке определяется строка из четырех символов и связыва ется с именем S. В следующей строке выполняются две операции дос тупа к элементам по индексам: S[0] возвращает элемент со смещением 0 от начала (односимвольную строку 's'), а S[2] возвращает элемент со смещением 2 от конца (что эквивалентно смещению (4 + 2) от нача ла). Смещения и срезы отображаются на элементы последовательно сти, как показано на рис. 7.1. 1 Последняя строка в предыдущем примере демонстрирует операцию извлечения среза (slicing). Получение среза можно считать некоторой формой синтаксического анализа, особенно при работе со строками – она позволяет извлекать целые участки (подстроки) за одно действие. Операция получения среза может использоваться для извлечения столбцов данных, обрезания ведущих и завершающих блоков текста и тому подобного. Позже в этой же главе мы рассмотрим другой при мер использования операции получения среза для синтаксического ана лиза строки. 1 Математически более подготовленные читатели (и студенты в моих клас сах) иногда обнаруживают здесь небольшую асимметрию: самый левый элемент имеет смещение 0, а самый правый имеет смещение –1. Увы, в языке Python отсутствует такая вещь, как значение –0. [начало:конец] По умолчанию используются начало и конец последовательности Индексы указывают позиции, в которых будут выполнены «разрезы» 2 1 2 1 0 [ : : ] S L I С E O F S P A M Рис. 7.1. Смещения и срезы: положительные смещения отсчитываются от левого конца (первый элемент имеет смещение 0), а отрицательные отсчитываются от правого конца (последний элемент имеет смещение –1). При выполнении операций индексации и получения среза можно использовать любые виды смещений Строки в действии 193 Как же выполняется операция получения среза? Когда производится индексирование объекта последовательности, такого как строка, парой смещений, разделенных двоеточием, интерпретатор Python возвраща ет новый объект, содержащий непрерывную область, определяемую па рой смещений. Значение смещения слева от двоеточия обозначает ле вую границу (включительно), а справа – верхнюю границу (она не вхо дит в срез). Интерпретатор извлекает все элементы от нижней границы до верхней, но верхняя граница в срез не включается. Если левая и пра вая граница опущены, по умолчанию принимаются значения, равные 0 и длине объекта, из которого извлекается срез, соответственно. Например, для только что рассмотренного примера выражение S[1:3] вернет элементы со смещениями 1 и 2. То есть будут извлечены второй и третий элементы, и операция остановится перед четвертым элемен том со смещением, равным 3. Выражение S[1:] вернет все элементы, расположенные за первым, – за значение верхней границы, которая в выражении опущена, по умолчанию принимается длина строки. На конец, выражение S[:1] вернет все элементы, кроме последнего, – за значение нижней границы по умолчанию принимается 0, а индекс – 1 соответствует последнему элементу, который в срез не включается. Все это может показаться на первый взгляд слишком замысловатым, но операции извлечения отдельных элементов и срезов превратятся в простые и мощные инструменты, как только вы ими овладеете. Если вы забыли, как выполняется срез, попробуйте получить его в интерак тивном сеансе. В следующей главе вы увидите, что существует воз можность изменить целый раздел определенного объекта одной инст рукцией, достаточно лишь выполнить операцию присваивания срезу. Далее приводится краткий обзор для справки: • Операция индексирования (S[i]) извлекает компоненты по их сме щениям: • Первый элемент имеет смещение, равное 0. • Отрицательные индексы определяют смещения в обратном поряд ке – от конца, или справа. • Выражение S[0] извлекает первый элемент. • Выражение S[2] извлекает второй с конца элемент (так же как и выражение S[len(S)2]). • Операция извлечения подстроки (S[i:j]) извлекает непрерывный раздел последовательности: • Элемент с индексом, равным верхней границе, не включается в срез. • Если границы не указаны, по умолчанию они принимаются рав ными 0 и длине последовательности. • Выражение S[1:3] извлекает элементы со смещениями от 1 до 3 (не включая элемент со смещением 3). 194 Глава 7. Строки • Выражение S[1:] извлекает элементы, начиная со смещения 1 и до конца (длина последовательности). • Выражение S[:3] извлекает элементы, начиная со смещения 0 и до 3 (не включая его). • Выражение S[:1] извлекает элементы, начиная со смещения 0 и до последнего (не включая его). • Выражение S[:] извлекает элементы, начиная со смещения 0 и до конца – это эффективный способ создать поверхностную ко пию последовательности S. Последний пункт списка – это самый обычный трюк: с его помощью создается полная поверхностная копия объекта последовательности, то есть объект с тем же значением, но расположенный в другой области памяти (подробнее о копировании объектов рассказывается в главе 9). Этот прием не очень полезен при работе с неизменяемыми объектами, такими как строки, но его ценность возрастает при работе с объекта ми, которые могут изменяться, – такими как списки. В следующей главе вы узнаете, что синтаксис операции доступа к элементам после довательности по смещениям (квадратные скобки) также применим для доступа к элементам словарей по ключам – операции выглядят одинаково, но имеют разную интерпретацию. Расширенная операция извлечения подстроки: третий предел В версии Python 2.3 в операцию извлечения подстроки была добавлена поддержка необязательного третьего индекса, используемого как шаг (иногда называется как шаг по индексу). Величина шага добавляется к индексу каждого извлекаемого элемента. Полная форма записи опе рации извлечения подстроки теперь выглядит так: X[I:J:K]. Она озна чает: «Извлечь все элементы последовательности X, начиная со смеще ния I, вплоть до смещения J1, с шагом K». Третий предел, K, по умол чанию имеет значение 1, именно по этой причине в обычной ситуации извлекаются все элементы среза, слева направо. Однако, если явно указать значение третьего предела, его можно использовать, чтобы пропустить некоторые элементы или полностью изменить их порядок. Например, выражение X[1:10:2] вернет каждый второй элемент после довательности X в диапазоне смещений от 1 до 9 – то есть будут выбра ны элементы со смещениями 1, 3, 5, 7 и 9. Как правило, по умолчанию первый и второй пределы принимают значения 0 и длину последова тельности соответственно, поэтому выражение X[::2] вернет каждый второй элемент от начала и до конца последовательности: >>> S = 'abcdefghijklmnop' >>> S[1:10:2] 'bdfhj' >>> S[::2] 'acegikmo' Строки в действии 195 Можно также использовать отрицательное значение шага. Например, выражение "hello"[::1] вернет новую строку "olleh". Здесь первые две границы получают значения по умолчанию – 0 и длина последова тельности, а величина шага, равная – 1, указывает, что срез должен быть выбран в обратном порядке – справа налево, а не слева направо. В результате получается перевернутая последовательность: >>> |