Similar presentations:
Алгоритмы и программирование. Очники. Лекция 4
1. Алгоритмизация и программирование
Доцент Шорина Татьяна ВладиславовнаАлгоритмизация и программирование
Часть 4. Базовые типы данных. Строки
2. Базовые типы данных. Строки
Строки допускается использовать для представления почти всего, что можеткодироваться как текст или байты. В отношении текста сюда входят символы и
слова (скажем, ваше имя), содержимое текстовых файлов, загруженное в
память, адреса в Интернете, исходный код Python и т.д.
Python сопровождаются мощным набором инструментов обработки. Кроме того, в
отличие от языков, подобных С, в Python не предусмотрен отдельный тип для
индивидуальных символов; взамен применяются односимвольные строки.
Строго говоря, строки Python относятся к категории неизменяемых
последовательностей, а это означает, что содержащиеся в них символы имеют
позиционный порядок слева направо и не могут быть модифицированы на
месте.
На самом деле строки являются первым представителем более крупного класса
объектов, называемых последовательностями. Операции над строками, будут
работать с другими типами последовательностей, которые мы рассмотрим
позже, такими как списки и кортежи.
В плане обработки строки поддерживают операции выражений, такие как
конкатенация (объединение строк), нарезание (срезы, извлечение частей),
индексация (извлечение по смещению) и т.д. Помимо операций выражений
Python также предоставляет набор строковых методов, которые реализуют
общие задачи, специфичные для строк, и модули для решения более сложных
задач вроде сопоставления с образцом.
3. Распространенные строковые литералы и операции
4. Распространенные строковые литералы и операции
В общем и целом строки в Python использовать довольно легко. Самой сложнойсвязанной с ними вещью следует считать, наличие слишком многих способов
их записи в коде:
одинарные кавычки — ‘spa "га ‘;
двойные кавычки — “spa 'm”;
утроенные кавычки – “””spam spam . . . “””
5. Базовые типы данных. Строки
Среди строк символы одинарных и двойных кавычек взаимозаменяемы. То естьстроковые литералы можно записывать заключенными либо в две одинарных,
либо в две двойных кавычки — две формы работают одинаково и возвращают
объект того же самого типа. Например, следующие две строки идентичны:
>>> ’shrubbery’, "shrubbery”
('shrubbery', 'shrubbery')
Причина поддержки обеих форм связана с тем, что она позволяет внедрять символ
кавычки другого вида внутрь строки, не отменяя его с помощью обратной
косой черты. Вы можете внедрять символ одинарной кавычки в строку,
заключенную в символы двойной кавычки и наоборот:
>>> ’knighf”s', ”knight’s”
(’knighf”s’, “knight's”)
В целом предпочтение отдается применению одинарных кавычек вокруг строк, т.к.
их чуть легче читать. Обратите внимание, что запятая здесь важна. Без нее
Python выполняет автоматическую конкатенацию соседних строк в любом
выражении, хотя почти так же просто поместить между ними операцию +,
чтобы инициировать конкатенацию явно:
>>> title = "Meaning " ‘of’ " Life"
# Неявная конкатенация
>>> title
'Meaning of Life'
6. Базовые типы данных. Строки
Кроме того, Python везде выводит строки в одинарных кавычках, если только они небыли внедрены. При необходимости вы можете также внедрять символы
кавычек, отменяя их посредством обратной косой черты:
>>> 'knight\'s', "knight\"s"
("knight's", ' knighf”s')
Обратная косая черта используется для введения специальных кодировок символов,
известных как управляющие последовательности.
Управляющие последовательности позволяют внедрять в строки символы, которые
не могут быть легко набраны на клавиатуре. Символ \ и один или более
следующих за ним символов в строковом литерале в результирующем строковом
объекте заменяются одиночным символом, который имеет двоичное значение,
указанное управляющей последовательностью. Скажем, вот пятисимвольная
строка, в которую внедрены символы новой строки и табуляции:
>>> s = 'a\nb\tc‘
>>> print (s)
а
b
с
Чтобы выяснить, сколько действительных символов содержится в строке,
применяйте встроенную функцию len, которая возвращает фактическое
количество символов в строке независимо от того, каким образом они
кодируются или отображаются:
>>> len(s)
5
7. Базовые типы данных. Строки
Некоторые управляющие последовательности позволяют встраивать абсолютныедвоичные значения в символы строки. Скажем, вот пятисимвольная строка, в
которую встраиваются два символа с нулевыми двоичными значениями
(представленные как восьмеричные управляющие последовательности).
>>> s = ’a\0b\0c'
>>> s
’a\x00b\x00c'
>>> len(s)
5
8. Неформатированные строки подавляют управляющие последовательности
Управляющие последовательности удобны для внедрения кодов специальныхсимволов внутрь строк. Тем не менее, иногда специальная трактовка обратной
косой черты для введения управляющей последовательности может вызывать
затруднения, попытка открыть файл, передавая в качестве аргумента имя файла,
которое выглядит примерно так:
myfile = open(’С:\new\text.dat', ’w')
Предполагается, что открывается файл по имени text.dat в каталоге C:\new. Проблема
здесь в том, что \п обозначает символ новой строки, a \t заменяется табуляцией. В
действительности такой вызов open пытается открыть файл с именем С: {новая
строка) ew (табуляция) ext.dat, приводя к непонятным результатам.
Как раз в таких ситуациях становятся полезными неформатированные строки. Если
прямо перед открывающей кавычкой строки указать букву г (в нижнем или
верхнем регистре), тогда механизм отмены отключается. В итоге Python сохраняет
символы обратной косой черты буквально, в точности как они набраны.
myfile = open(г'С:\new\text.dat', ’w’)
В качестве альтернативы, поскольку две обратные косые черты на самом деле
представляют собой управляющую последовательность для одной обратной косой
черты, предохранить обратные косые черты в имени файла можно, просто
продублировав их:
myfile = open(’С:\\new\\text.dat', ’w’)
9. Базовые типы данных. Строки
Фактически сам Python временами использует такую схему дублирования, когдавыводит строки с внедренными обратными косыми чертами:
>>> path « г’С:\new\text.dat'
>>> path
# Отображает в формате, как в коде
# Python ’С:\\new\\text.dat'
>>> print (path)
# Отображает в формате,
# дружественном к пользователю
С:\new\text.dat
>>> len (path) # Длина строки
15
Как и в случае числового представления, стандартный формат в интерактивной
подсказке предусматривает отображение результатов в виде, который они
имели бы, находясь в коде, а потому отменяет обратные косые черты в выводе.
Оператор print поддерживает более дружественный к пользователю формат,
отображающий по одной обратной косой черте в каждом месте.
Чтобы убедиться в этом, можете проверить результат встроенной функции len,
которая возвращает количество символов в строке независимо от форматов
отображения. Если вы подсчитаете символы в выводе print (path), то заметите,
что на каждую обратную косую черту приходится по одному символу, а всего в
строке 15 символов.
10. Утроенные кавычки представляют многострочные блочные строки
До сих пор мы видели в действии одинарные кавычки, двойные кавычки,управляющие последовательности и неформатированные строки. В Python также
имеется формат строковых литералов с утроенными кавычками, иногда
называемый блочной строкой, т.е. синтаксическим удобством для написания
многострочных текстовых данных.
Такая форма начинается с трех кавычек (одинарных или двойных), за которыми
следует любое количество строк текста, и заканчивается теми же самыми
утроенными кавычками, что и в начале.
Одинарные и двойные кавычки, встроенные в текст строки, могут отменяться, но не
обязательно — строка не закончится до тех пор, пока Python не встретит три
неотмененных кавычки того же вида, который применялся в начале литерала.
>>> mantra = ’’’’’’Always look
... on the bright
. . . side of life.”””
>>>
>>> mantra
'Always look\n on the bright\nside of life.’
В любом случае Python собирает весь текст между утроенными кавычками в
единственную многострочную строку с внедренными символами. Каким образом
интерпретируется строка с помощью print:
>>> print(mantra)
Always look
on the bright
side of life.
11. Утроенные кавычки представляют многострочные блочные строки
Фактически строки, заключенные в утроенные кавычки, будут сохранять весьнаходящийся между ними текст, в том числе любые символы справа от кода,
которые могли задумываться как комментарии. Поэтому не поступайте так —
помещайте комментарии до или после текста в утроенных кавычках либо
используйте упомянутую ранее автоматическую конкатенацию соседних строк,
с явными символами новой строки в случае необходимости и окружающими
круглыми скобками, чтобы разрешить распространение на несколько строк:
>>> menu = “””spam # Комментарии здесь добавляются к строке!
. . . eggs
# То же самое
. . .“””
>>> menu
’spam # Комментарии здесь добавляются к строке! \neggs # То же
самое\п'
>>> menu = (
. . . ”spam\n”
# Комментарии здесь игнорируются,
. . . "eggs\n"
# но символы новой строки не являются
# автоматическими
... )
>>> menu
’spam\neggs\n’
Строки в утроенных кавычках удобны в любое время, когда в программе нужен
многострочный текст, скажем, для внедрения в файлы исходного кода Python
многострочных сообщений об ошибках или кода HTML, XML. Вы можете
внедрять такие блоки прямо в свои сценарии, помещая их в утроенные
кавычки.
12. Базовые строчные операции
Вы можете выполнять конкатенацию строк, используя операцию +, и повторять ихс применением операции *:
>>> len( ’abc’)
3
>>> ’abc’ + ’def’
’abcdef’
>>> ’Ni! ’ * 4
’Ni!Ni!Ni!Ni!’
# Длина: количество элементов
# Конкатенация: новая строка
# Повторение: подобно "Ni!” + "Ni!” + ...
Встроенная функция len возвращает длину строки (или любого другого объекта,
имеющего длину). Формально сложение двух строк посредством операции +
создает новый строковый объект с объединенным содержимым ее операндов,
а повторение с помощью операции * подобно добавлению строки к самой
себе несколько раз. В обоих случаях Python позволяет создавать строки
произвольных размеров.
Например, для вывода 80 символов минуса вы можете сами посчитать до 80 или
поручить это Python:
>>> print(‘ -----...и еще... —-’)
>>> print(‘-’* 80)
# 80 символов трудный способ
# 80 символов легкий способ
Обратите внимание, что здесь уже работает перегрузка операций: мы используем
те же самые операции + и *, которые выполняют сложение и умножение, когда
применяются к числам. Язык Python делает правильную операцию, поскольку
ему известны типы объектов в операндах.
13. Базовые строчные операции
Но будьте осторожны: правила не настолько либеральны, как вы могли быожидать. Скажем, Python не разрешает смешивать числа и строки в
выражениях с операцией +: ’abc'+9 приводит к ошибке вместо автоматического
преобразования int(9) в строку.
Мы также можем проходить по строкам в циклах, используя операторы for,
которые повторяют действия, и проверять членство для символов и подстрок
посредством операции выражения in, которая по существу является поиском.
В случае подстрок операция in очень похожа на метод str. find (), раскрываемый
далее, но возвращает булевский результат, а не позицию подстроки:
>>> my job = "hacker”
>>> for с in myjob: print (с, end=’ ’) # Проход по элементам
# с выводом каждого ‘h a c k e r’
>>> "k” in myjob
# Найден
True
>>> "z" in myjob
# He найден
False
>>>’spam’ in ’abcspamdef’
# Поиск подстроки без
True
# возвращения позиции
True
В цикле for переменной по очереди присваиваются элементы из
последовательности (здесь строки) и для каждого элемента выполняется один
или больше операторов. В действительности переменная с становится
курсором, проходящим по символам строки.
14. Индексация и нарезание
Поскольку строки определяются как упорядоченные коллекции символов, мыможем получать доступ к их компонентам по позиции. В Python символы из
строки извлекаются посредством индексации — предоставления числового
смещения желаемого компонента в квадратных скобках после строки.
Результатом будет односимвольная строка в указанной позиции.
Как и в языке С, смещения в Python начинаются с 0 и заканчиваются величиной на
единицу меньше длины строки. Тем не менее, в отличие от С язык Python также
позволяет извлекать элементы из последовательностей, таких как строки, с
применением отрицательных смещений, которые представляют собой отсчет в
обратном направлении с конца.
>>> s = ’ spam’
>>> S[0] , S[-2]
(’s’, ’а’)
>>> S[1:3], S[1:], S[:-1]
(’ра’, ’pam’, ’spa’)
# Индексация с начала или с конца
# Нарезание: извлечение сегмента
В первой команде определяется четырехсимвольная строка и присваивается имени
S. В следующей команде она индексируется двумя путями: S [0] извлекает
элемент по смещению 0 слева — односимвольную строку ’s’; S [-2 ] получает
элемент по смещению 2 с конца, что эквивалентно смещению (4 + (-2)) с начала.
15. Индексация и нарезание
Индексация (S[±]) извлекает компоненты по смещениям:первый элемент находится по смещению 0;
отрицательные смещения означают отсчитывание с конца или справа;
S [ 0 ] извлекает первый элемент;
S [ -2 ] извлекает второй элемент с конца (подобно S [ len (S) -2 ]).
Нарезание (S[i:j]) извлекает непрерывные сегменты последовательности:
верхняя граница является исключающей;
если границы не указаны, тогда по умолчанию для них принимаются 0 и длина
последовательности;
S [ 1:3 ] извлекает элементы, которые начинаются со смещения 1 и
заканчиваются по смещению 3, не включая его;
S [1: ] извлекает элементы, начиная со смещения 1 и до конца;
S [: 3] извлекает элементы, которые начинаются со смещения которые
начинаются со смещения 0 и заканчиваются по смещению 3, не включая его;
S [ :-1] извлекает элементы, начиная со смещения 0 и заканчивая последним
элементом, но не включая его;
S [ : ] извлекает элементы, начиная со смещения 0 и до конца — создает копию
верхнего уровня S.
Расширенное нарезание (S [i: j :k] ) принимает шаг (или страйд (большой шаг)) к,
который по умолчанию равен +1:
позволяет пропускать элементы и менять порядок на противоположный, как
объясняется далее.
16. Расширенное нарезание: третий предел и объекты срезов
Для выражений срезов имеется поддержка необязательного третьего индекса,используемого в качестве шага. Шаг добавляется к индексу каждого
извлеченного элемента. Теперь развитая форма среза выглядит как X [ I : J : К] и
означает “извлечь все элементы в X, начиная со смещения I и заканчивая
смещением J-1, с шагом К”. Третий предел, К, по умолчанию устанавливается в +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’
Можно также использовать отрицательный страйд для накапливания элементов в
противоположном порядке.
>>> 8 = ’hello’
>>> S[: : -1]
# Смена порядка, следования элементов на
# противоположный
’olleh’
17. Расширенное нарезание: третий предел и объекты срезов
При отрицательном шаге смысл первых двух границ по существу изменяется напротивоположный. Таким образом, срез S [5 : 1 : -1] извлекает элементы со
второго по пятый в обратном порядке (результат содержит элементы по
смещениям 5, 4, 3 и 2):
>>> S = 'abcedfg'
>>> S[5:1:-1]
'fdec'
# Смысл границ изменяется
Нарезание эквивалентно индексации с помощью объекта среза, что важно для
разработчиков классов.
>>>‘spam’[1:3]
# Синтаксис нарезания
'ра'
>>> spam’[slice(1, 3)]
# Индексация посредством объектов срезов
’ра’
>>> ‘spam’[::-1]
’maps’
>>> spam’[slice( None, None, -1)]
’maps’
Срезы также часто применяются для очистки строк, прочитанных из входных
файлов. Если известно, что последним символом в строке будет конец строки
(\n), то вы можете избавиться от него с помощью выражения line [: -1 ], которое
извлекает все символы кроме последнего (по умолчанию нижняя граница
принимается равной 0). В обоих случаях срезы выполняют работу логики,
которая должна быть явной в языках более низкого уровня.
18. Инструменты преобразования строк
Python не разрешает смешивать числа и строки в выражениях, мы не можемскладывать число и строку в Python, даже если эта строка выглядит похожей на
число (т.е. содержит только цифры):
# Python З.Х
>>> „42" + 1
TypeError: Can’t convert ’int’ object to str implicitly
Ошибка типа: нельзя преобразовывать объект int в str неявно.
>>> int("42"), str(42)
(42, ’42')
# Преобразование из строки и в строку
Функция int преобразует строку в число, а функция str преобразует число в его
строковое представление (по существу в то, как число выглядит, когда
выводится посредством print).
>>> s=‘42’
>>> int(S) + 1
43
>>> S + str(1)
' 421'
# Принудительно применить сложение
# Принудительно применить конкатенацию
Похожие встроенные функции поддерживают преобразования чисел с плавающей
точкой в строки и обратно:
>>> str(3.1415), float("1.5")
( '3.1415', 1.5)
>>> text = "1.234Е-10"
>>> float (text)
1.234е-10
19. Преобразования кодов символов
Передавая символ встроенной функции ord, которая возвратит действительноедвоичное значение, используемое для представления соответствующего
символа в памяти.
Функция chr выполняет обратное преобразование, принимая целочисленный код и
возвращая надлежащий символ:
>>> ord( 's')
115
>>> chr (115)
' s'
Например, чтобы перейти к следующему символу, его нужно преобразовать и
выполнить математическое действие с целым числом:
>>>
>>>
>>>
’6’
>>>
>>>
'7'
s = ’5’
s = chr(ord(s) + 1)
s
s = chr(ord(s) + 1)
s
20. Изменение строк
Термин “неизменяемая последовательность” означает, что мы не можемизменять строку на месте — скажем, присваивая по индексу:
>>> s = ’spam’
>>> S[0] = ’х’
# Возникает ошибка!
TypeError: ’str’ object does not support item assignment
Ошибка типа: объект str не поддерживает присваивание в отношении элементов.
Тогда каким же образом модифицировать текстовую информацию в Python? Чтобы
изменить строку, обычно необходимо создать и присвоить новую строку с
применением таких инструментов, как конкатенация и нарезание, и затем при
желании присвоить результат первоначальному имени строки:
>>> S = S + ’SPAM!’
# Чтобы изменить строку, нужно создать новую
>>> S
’spamSPAM!'
>>> S = S[: 4] + ’Burger’ + S[-1]
>>> S
’spamBurger!’
В первом примере подстрока добавляется в конец S посредством конкатенации. На
самом деле здесь создается новая строка и присваивается переменной S, но vы
можеv думать об этом как об “изменении” исходной строки.
Во втором примере четыре символа заменяются шестью с помощью нарезания,
индексации и конкатенации.
21. Строковые методы
Методы — это просто функции, которые ассоциированы с определеннымиобъектами и действуют на них. Формально они являются атрибутами,
прикрепленными к объектам, которые ссылаются на вызываемые функции,
всегда имеющие в своем распоряжении подразумеваемый объект.
Говоря точнее, функции представляют собой пакеты кода, а вызовы методов
комбинируют две операции — извлечение атрибута и вызов.
Извлечения атрибутов
Выражение в форме объект, атрибут означает “извлечь значение атрибута в
объекте”.
Выражения вызовов
Выражение в форме функция (аргументы) означает “вызвать код функции, передав
ему ноль или большее количество разделенных запятыми объектов
аргументов, и возвратить результирующее значение функции".
Объединение двух операций вместе позволяет вызвать метод объекта. Выражение
вызова метода:
объект. метод (аргументы)
оценивается слева направо — Python сначала извлечет метод из объекта и затем
вызовет его, передавая объект и аргументы.
>>> s = ’spam’
>>> result = S.find(’pa’)
# Вызов метода find для поиска 'ра ' в
# строке S
22. Методы строк
23. Методы строк
В общем случае для создания нового значения из существующей строки выконструируете новую строку с помощью операций вроде нарезания и
конкатенации.
Скажем, для замены двух символов в середине строки можно применять такой
код:
>>> S = 'spammy'
>>> S = S[:3] + ’хх' + S[5:]
>>> S
’spaxxy’
# Нарезать сегменты из S
Но если нужно только заменить подстроку, тогда можно использовать метод
replace:
>>> S = 'spammy'
>>> S = S. replace (’ mm ’ , 'хх')
>>> S
’spaxxy’
# Заменить все mm на хх в S
Метод replace является более универсальным, чем вытекает из приведенного кода.
Он принимает в качестве аргументов исходную подстроку (любой длины) и
строку (любой длины), которой должна быть заменена исходная подстрока, и
выполняет глобальный поиск и замену:
>>>’aa$bb$cc$dd’.replace('$', ’SPAM’)
’aaSPAMbbSPAMccSPAMdd‘
В такой роли метод replace может применяться как инструмент для реализации
замен по образцу (например, в форматированных бланках).
24. Методы строк
Если требуется заменить одну подстроку фиксированного размера, которая можетрасполагаться по любому смещению, то можно сделать замену снова или
выполнить поиск подстроки посредством метода find и затем произвести срез:
>>> S = 'xxxxSPAMxxxxSPAMxxxx’
>>> where = S.find('SPAM')
# Поиск позиции
>>> where
# Нашлась по смещению 4
4
>>> S = S[:where] + 'EGGS’ + S[(where+4) :]
>>> S
’xxxxEGGSxxxxSPAMxxxx’
Метод find возвращает смещение, по которому обнаруживается подстрока (по
умолчанию выполняя поиск с начала), или -1, если подстрока не найдена. Как
упоминалось ранее, find представляет собой операцию поиска подстроки,
подобную выражению in, но возвращает позицию найденной подстроки.
Еще один вариант предусматривает применение метода replace с третьим
аргументом, чтобы ограничить его единственной подстановкой:
>>> S = ' xxxxSPAMxxxxSPAMxxxx'
>>> S.replace('SPAM' , 'EGGS')
# Заменить все
'xxxxEGGSxxxxEGGSxxxx'
>>> S. replace (' SPAM' , 'EGGS', 1) # Заменить одну
’xxxxEGGSxxxxSPAMxxxx’
Обратите внимание, что replace каждый раз возвращает новый строковый объект.
Поскольку строки неизменяемы, метод никогда по-настоящему не модифицирует
исходную строку на месте.
25. Методы строк
Тот факт, что операции конкатенации и метод replace каждый раз генерируютновые строковые объекты, на самом деле является потенциальным
недостатком их использования для изменения строк. Если нужно применить
много изменений к очень крупной строке, то производительность сценария
можно улучшить, преобразовав строку в объект, который поддерживает
изменения на месте:
>>> S = 'spammy'
>>> L = list(S)
>>> L
[’s', 'p', 'a', 'm', 'm', 'y']
Встроенная функция list (вызов конструктора объекта) строит новый список из
элементов любой последовательности — в данном случае извлекая символы
строки и помещая их в список. Когда строка приобретает такую форму, в нее
можно вносить множество изменений без генерации новой копии при каждом
изменении:
>>> L[3] = 'х'
>>> L[4] = 'х'
>>> L
['s', 'р', 'а', 'х', ' х', 'у']
# Работает для списков, но не для строк
Если после внесения изменений список необходимо преобразовать обратно в
строку (скажем, для записи в файл), тогда понадобится вызвать метод join:
>>> S = ' ' . join (L)
>>> S
'spaxxy'
26. Методы строк
На первый взгляд метод join может показаться слегка непонятным. Поскольку joinпредставляет собой метод строк (не списков), он вызывается через заданный
разделитель. Метод join объединяет вместе строки из списка (или другого
итерируемого объекта) с разделителями между элементами списка; здесь в
качестве разделителя используется пустая строка, чтобы преобразовать список
в строку.
В более общем случае можно указывать любой строковый разделитель
итерируемый объект со строками:
>>> ' SPAM'. join (['eggs' , 'sausage', 'ham', 'toast'])
'eggsSPAMsausageSPAMhamSPAMtoast‘
Еще одной распространенной ролью строковых методов является простая форма
разбора текста, т.е. анализа структуры и извлечения подстрок. Для извлечения
подстрок по фиксированным смещениям мы можем задействовать методики
нарезания:
>>> line = ’ааа ЬЬЬ ссс'
>>> col1 = line [0:3]
>>> соl3 = line [8:]
>>> coll
’ ааа ’
>>> соl3
’ ссс ’
27. Методы строк
Поля данных здесь расположены по фиксированным смещениям и потому могутбыть вырезаны из исходной строки. Такой прием подходит для разбора при
условии, что компоненты данных имеют фиксированные позиции. Если взамен
данные разделены посредством какого-нибудь разделителя, тогда извлечь
компоненты можно путем разбиения. Такой прием будет работать, даже когда
данные находятся в произвольных позициях внутри строки:
>>> line = 'ааа ЬЬЬ ссс’
>>> cols = line.split()
>>> cols
[ ’ааа’, 'bbb', ’ссс’]
Строковый метод split разбивает строку на список подстрок согласно строке
разделителя. В приведенном примере разделитель не указан, поэтому по
умолчанию принимаются пробельные символы — строка разбивается по
группам из одного или большего числа пробелов, табуляций и новых строк, а
результатом будет список подстрок.
>>> line == ’bob, hacker, 40 ’
>>> line. split (' , ')
[’bob’, 'hacker’, ’40’]
Разделители могут быть длиннее одного символа:
>>> line = "i’mSPAMaSPAMlumberjack"
>>> line, split ("SPAM")
[”i’m“, 'a', ’lumberjack']
.
28. Методы строк
Другие строковые методы играют более специфичные роли — например, удаляютпробельные символы в конце строки текста, выполняют преобразование регистра
символов, проверяют содержимое и выясняют наличие подстроки в конце или в
начале:
>>> line = "The knights who say Ni!\n"
>>> line.rstrip()
'The knights who say Ni!'
>>> line.upper()
'THE KNIGHTS WHO SAY NI! \n'
>>> line.isalpha()
False
>>> line.endswith( 'Ni! \n')
True
>>> line.startswith(’The')
True
Для достижения тех же результатов, которые получаются посредством строковых
методов, иногда применяются альтернативные приемы; скажем, операцию
членства in можно использовать для проверки наличия подстроки, а операции
определения длины и нарезания — для имитации endswith \:
>>>
True
>>>
True
>>>
>>>
True
>>>
line.find('Ni') ’ = -1 # Поиск через вызов метода или выражение
'Ni' in line
sub = 'Ni!\n'
line.endswith(sub)
# Проверка наличия подстроки в конце
# через вызов метода или срез
line[-len(sub) :] == sub
29. Выражения форматирования строк
Хотя мы многое можем сделать посредством уже описанных строковых методов иопераций над последовательностями, Python также предлагает более развитый
способ для объединения задач строковой обработки — форматирование строк
позволяет выполнять множество подстановок, специфических для типов, в строке
за единственный шаг.
Выражение форматирования строк: ’ . . . %s. . . ’ % (значения)
Первоначальный прием, доступный с момента появления Python, основан на модели
printf языка С и повсеместно встречается в большинстве существующего кода.
Вызов метода форматирования строк: ’. . format (значения)
Основы выражений форматирования
Когда операция % применяется к строкам, она предоставляет простую методику
форматирования значений в виде строк согласно определению формата. Вкратце
операция % предлагает компактный способ записи для множества подстановок
строк одновременно вместо создания и конкатенации отдельных частей.
Чтобы сформатировать строку, выполните следующие действия.
1. Слева от операции % укажите строку формата, содержащую одну или более
встроенных целей преобразования, каждая из которых начинается с %
(например, %d).
2. Справа от операции % укажите объект (или объекты, внедренные в кортеж),
который необходимо вставить в строку формата слева на месте цели (или целей)
преобразования.
30. Выражения форматирования строк
Например, целое число 1 заменяет %d в строке формата слева, а строка 'dead’заменяет %s. Результатом будет новая строка, отражающая описанные две
подстановки, которую можно вывести или сохранить для дальнейшего
использования:
>>>’That is %d %s bird!’ % (1, ’dead’)
That is 1 dead bird!
# Выражение формата
Говоря формально, выражения форматирования строк обычно необязательны — в
целом вы можете делать похожую работу с помощью множества конкатенаций и
преобразований. Однако форматирование позволяет объединить много шагов в
единственную операцию.
>>> exclamation = 'Ni'
>>>’The knights who say %s!’ % exclamation # Подстановка строки
’The knights who say Ni!'
>>>’%d %s %g you’ % (1, 'spam', 4.0)
# Подстановки,
# специфичные для типов
’ 1 spam 4 you ’
>>>’%s — %s — %s’ % (42, 3.14159, [1, 2, 3]) # Все типы
# соответствуют цели %s
’42 — 3.14159 — [1, 2, 3] ’
В первом примере строка ’Ni ’ подставляется в цель слева, заменяя %s.
Во втором примере в целевую строку вставляются три значения. Операция %
выражения форматирования ожидает в своей правой стороне либо одиночный
элемент, либо кортеж из одного или более элементов.
В третьем снова вставляются три значения, целое число, число с плавающей точкой
и списковый объект, но все цели слева указаны как % s, что обозначает
преобразование в строку.
31. Расширенный синтаксис выражений форматирования
Для более сложного форматирования, специфичного для типов, в выраженияхформатирования можно использовать любые коды преобразования типов,
перечисленные в табл.
32. Выражения форматирования строк
На самом деле цели преобразований в строке формата в левой части выраженияподдерживают различные операции преобразования с довольно сложным
синтаксисом. Общая структура целей преобразований выглядит следующим
образом:
% [ (имя ключа) ] [флаги] [ширина] [. точность] код типа
Между % и символом кода типа можно делать любое из описанных ниже
действий:
указывать имя ключа для индексации словаря, используемого в правой
части выражения;
перечислять флаги, которые указывают аспекты вроде выравнивания влево
(-), знак числа (+), пусто перед положительными числами и — для
отрицательных чисел (пробел) и дополнение нулями (0);
задавать общую минимальную ширину поля для подставляемого текста;
устанавливать количество цифр, отображаемых после десятичной точки
(точность), для чисел с плавающей точкой.
Части ширина и точность также можно записывать как * для указания на то, что
они должны брать свои значения из следующего элемента во входных
значениях правой части выражения.
33. Выражения форматирования строк
Следующая строка форматирует целые числа по умолчанию и затемшестисимвольное поле с выравниванием влево и дополнением нулями:
Форматы %e, %f и %g отображают числа с плавающей точкой по-разному как видно
во взаимодействии ниже. Здесь %Е — то же, что и %е, но экспонента выводится
в верхнем регистре. Кроме того, g выбирает форматы по содержимом}7 числа
(формально определено использование экспоненциального формата е, если
показатель степени меньше -4 или не меньше точности, и в противном случае
десятичного формата f со стандартной общей точностью 6 цифр):
Добиться дополнительных эффектов форматирования для чисел с плавающей
точкой можно, указывая выравнивание влево, дополнение нулями, знак числа,
общую ширину поля и количество цифр после десятичной точки:
34. Методы форматирования строк
Метод format строкового объекта, доступный в Python 2.6, 2.7 и З.Х, базируется наобычном синтаксисе вызова функций, а не на выражении. В частности, он
использует в качестве шаблона строку, на которой вызывается, и принимает
любое количество аргументов, которые представляют значения, подлежащие
подстановке согласно шаблону.
Применение метода format требует знания функций и вызовов, но в основном оно
прямолинейно. Фигурные скобки внутри строки, на которой метод вызывается,
обозначают цели подстановки и аргументы, вставляемые по позиции:
>>> template = ’{0}, {1} and {2}’
>>> template.format('spam', ’ham’, ’eggs')
’spam, ham and eggs‘
# По позициям
>>> template = ’{motto} {pork} and {food}' # По ключевым словам
>>> template.format(motto=’spam', pork='ham', food='eggs')
'spam, ham and eggs‘
>>> template = ' {motto}, {0} and {food} '
# По позициям и
# ключевым словам
>>> template.format('ham', motto='spam', food='eggs')
'spam, ham and eggs‘
>>> template = ’ {}, {} and {} '
# По относительным позициям
>>> template.format('spam', 'ham', 'eggs') # Нововведение Python 3.
'spam, ham and eggs'
35. Расширенный синтаксис методов форматирования
Для метода форматирования после обозначения цели с возможно пустойподстановкой мы используем двоеточие, за которым следует спецификатор
формата, указывающий размер поля, выравнивание и конкретный код типа.
{имя__поля компонент ! флаг_преобразования : спецификатор_формата}
Ниже приведено описание синтаксиса цели подстановки.
имя_поля — необязательное число или ключевое слово, идентифицирующее
аргумент, которое может быть опущено для применения относительной
нумерации аргументов в Python 2.7, 3.1 и более поздних версиях.
компонент — строка из нуля или большего числа ссылок .имя либо [индекс],
используемых для извлечения атрибутов и индексированных значений
аргумента, которая может быть опущена для применения всего значения
аргумента.
флаг_преобразования, если присутствует, начинается с символа !, за которым
следует г, s или а для вызова на значении встроенных функций герг, str или ascii
соответственно.
спецификатор_формата, если присутствует, начинается с символа :, за которым
следует текст, указывающий, каким образом значение должно быть
представлено, в том числе такие детали, как ширина поля, выравнивание,
дополнение, десятичная точность и т.д., и в конце необязательный код типа
данных.
36. Расширенный синтаксис методов форматирования
Часть спецификатор-формат а после символа двоеточия имеет собственныйрасширенный формат и формально описывается так (квадратные скобки
обозначают необязательные компоненты и записываться буквально не
должны):
[[заполнение] выравнивание] [знак] [#] [0] [ширина] [,] [.точность] [код_типа]
Здесь заполнение может быть любым заполняющим символом кроме { или };
выравнивание — <,>,= или ^ соответственно для выравнивания влево,
выравнивания вправо, дополнения символом знака или выравнивания по
центру; знак может быть + , - или пробелом, (запятая) требует запятой для
разделителя тысяч.
Компоненты ширина и точность почти такие же, как в выражении %; кроме того,
спецификатор__формата может также содержать вложенные строки формата {}
только с именами полей, чтобы получать значения из списка аргументов
динамически (что очень похоже на * в выражениях форматирования).
Параметры конструкции код_типа метода практически полностью совпадают с
параметрами, которые используются в выражениях % и были ранее
перечислены в табл., но метод форматирования разрешает также применять
код типа b для отображения целых чисел в двоичном виде (эквивалентен
использованию встроенной функции bin), код типа % для отображения знака
процента и только d для десятичных целых (i либо и не применяются).
Обратите внимание, что в отличие от спецификатора %s выражения код типа s
здесь требует аргумента в виде строкового объекта; для принятия любого типа
обобщенным образом код типа необходимо опустить.
37. Примеры использования методов форматирования
В следующих вызовах методов {0:10} означает первый позиционный аргумент вполе шириной 10 символов, {1: <10} — второй позиционный аргумент,
выровненный влево в поле шириной 10 символов.
В показанных ниже вызовах {2 : g} означает, что третий аргумент форматируется по
умолчанию согласно представлению с плавающей точкой g, {1: .2f} указывает
формат с плавающей точкой f с только двумя десятичными цифрами после
точки, а {2 : 0 6.2 f} добавляет поле шириной 6 символов и дополнением
нулями слева:
38. Методы форматирования строк
Метод format также поддерживает шестнадцатеричный, восьмеричный идвоичный форматы. На самом деле форматирование строк является
альтернативой использованию ряда встроенных функций, которые
форматируют целые числа для заданного основания системы счисления:
# Шестнадцатеричный, восьмеричный, двоичный
>>>’{0:Х}, {1:о}, {2:Ь}’.format(255, 255, 255)
’ FF, 377, 11111111‘
# Другие преобразования в/из двоичного
>>> bin(255), int (' 11111111 ’ , 2), 0b11111111
( ’0Ы1111111’ , 255, 255)
# Другие преобразования в/из шестнадцатеричного
>>> hex (255), int(’FF’, 16), OxFF #
(’Oxff’, 255, 255)
# Другие преобразования в/из восьмеричного
>>> oct(255), int('377’, 8), 0о377
(’ 0о377 ', 255, 255)
39. Просмотр последовательностей: while и for
Мы можем делать ручную индексацию также и в цикле for, если примените функциюrange с целью генерации списка индексов для прохода по ним. Процесс
многошаговый, но его вполне достаточно для генерации смещений, а не
элементов по этим смещениям:
>>> х
’spam’
>>> len(X)
4
>>> list (range (len (X)))
[О, 1, 2, 3]
>>>
>>> for i in range (len (X)) :
print(X[i] , end=’ ’)
spam
# Длина строки
# Все допустимые смещения в X
# Ручная итерация
# посредством range/len
Обратите внимание, что поскольку в примере производится проход по списку
смещений в X, а не по действительным элементам X, внутри цикла для извлечения
каждого элемента необходима индексация в X.
Хотя комбинации range/len в такой роли достаточно, вряд ли стоит считать ее лучшим
вариантом. Код может выполняться медленнее и требует большего объема
работы, нежели оправдано. Если только не существует специального требования
индексации, то лучше использовать простую форму цикла for в Python.
40. Просмотр последовательностей: while и for
Самый легкий и обычно наиболее быстрый способ прохода по последовательностивсегда предусматривает применение простого цикла for, т.к. Python
самостоятельно поддерживает большинство деталей:
>>> X = ’ spam’
>>> for item in X: print(itemz end=‘ ‘) # Простая итерация
spam
При использовании подобным образом цикл for внутренне обрабатывает все
детали автоматически. Если вам на самом деле необходимо взять на себя
логику индексации, то вы можете сделать это посредством цикла while:
>>> i = 0
>>> while i < len(X) :
...
print(X[i], end=‘ ‘)
...
i += 1
spam
# Итерация в цикле while
В качестве общего правила необходимо запомнить:
всякий раз, когда это возможно, применяйте for вместо while,
не используйте вызовы range в циклах for кроме крайних случаев,
более простое решение практически всегда будет лучшим.
Однако, как и в каждом хорошем правиле, есть масса исключений — что и
демонстрируется в следующем разделе.
41. Тасование последовательностей: range и len
Некоторые алгоритмы могут задействовать переупорядочениепоследовательностей — для генерации вариантов при поиске, для проверки
эффекта от разного упорядочения значений и т.д. Такие случаи могут требовать
смещения, чтобы разделять последовательности и снова собирать их вместе,
как показано ниже; целые числа диапазона предоставляют счетчик повторений
в первом и позицию для нарезания во втором:
>>> S = ’spam'
>>> for i in range(len(S)) :
# Для счетчиков повторений 0. .3
...
S = S[1:]+S[:1]
# Переместить начальный элемент в конец
…
print(S, end=' ')
pams amsp mspa spam
>>>
>>> S='spam’
>>> for i in range(len(S)) :
# Для позиций 0. .3
...
X = S [i: ] + S [: i]
# Задняя часть + передняя часть
...
print(X, end=' ’)
spam pams amsp mspa
Отследите приведенные циклы по одной итерации за раз, если они кажутся
непонятными. Второй цикл создает те же результаты, что и первый, но в другом
порядке, не изменяя в ходе дела исходную переменную. Из-за того, что оба
производят нарезание, чтобы получить части для объединения, они также
работают на последовательности любого типа и возвращают
последовательности того же типа, что и тасуемые.
42. Неполный обход: range или срезы
Случаи вроде приведенных в предыдущем примере являются эффективнымиприложениями для комбинации range/len. Мы можем также использовать
такую методику для пропускания элементов по мере продвижения:
>>> S = ' abcdefghijk ’
>>> list (range (0, len(S), 2))
[0, 2, 4, 6, 8, 10]
>>> for i in range (0, len(S), 2): print (S[i], end=' ’)
acegik
Здесь мы посещаем каждый второй элемент в строке S за счет перехода согласно
списку, сгенерированному функцией range. Для посещения каждого третьего
элемента измените третий аргумент range на 3 и т.д. Фактически применение
range подобным образом позволяет пропускать элементы в циклах, попрежнему сохраняя простоту циклической конструкции for.
Тем не менее, в наши дни это также вряд ли можно считать рекомендуемой
методикой в Python. Если вы действительно намереваетесь пропускать
элементы в последовательности, то расширенная форма выражения среза с
тремя пределами, обеспечивает более простой способ достижения той же
цели.
Например, для посещения каждого второго символа в S нарезайте со страйдом 2:
>>> S = ' abcdefghi jk ’
>>> for с in S [: : 2] : print (c, end= ’ ’)
acegik
Результат будет таким же, но код значительно легче для написания и восприятия
другими.