Строки в Python
- Понятие строки в Python
- Создание строк в Python
- Экранированные последовательности
- Доступ по индексу и срезы строк
- Операторы строк в Python
- Функции и методы строк в Python
- Метод форматирования строк
- Использование F-строк
- Краткие итоги параграфа
- Вопросы и задания для самоконтроля
Понятие строки в Python
Для хранения и представления текстовой информации в Python используются строки, которые представляют собой отдельный тип данных str. Говоря о тексте, я имею ввиду обычное содержимое текстовых файлов, исходный код программ, отдельные фразы, слова или даже символы.
Строки (от англ. strings) – это неизменяемые упорядоченные последовательности символов Юникода, которые используются в Python для хранения и представления текстовой информации. По умолчанию в скриптах используется кодировка UTF-8.
Важно помнить, что строки в Python относятся к неизменяемым последовательностям. Это значит, что отдельные символы в строке располагаются в определенном порядке слева направо, т.е. образуют последовательность, и могут быть получены при помощи своего индекса в этой последовательности, который для первого символа строки принимается равным нулю. Однако добавить новый символ, изменить или удалить уже существующий не получится, т.к. строки в Python неизменяемые. Можно создать измененную копию строки (что и делает большинство методов), но саму строку изменить нельзя.
Следует добавить, что строки в Python могут использоваться и для хранения двоичных значений байтов. Это может быть полезным при обработке файлов изображений, аудиофайлов, а также работе с упакованными данными. Для таких случаев доступны строковые типы bytes (строка байтов или по-другому неизменяемая байтовая строка) и bytearray (массив байтов или по-другому изменяемая байтовая строка). Оба типа мы рассмотрим подробнее в последней главе нашего учебника.
Создание строк в Python
Вписать литерал строки в код программы на языке Python довольно легко. Достаточно заключить требуемую последовательность символов в одинарные, двойные или тройные кавычки (см. пример №1).
# Присваиваем литерал строки в одинарных кавычках.
str_1 = 'Я – строка в одинарных кавычках.'
# Тип str_1: <class 'str'>.
print('Тип str_1:', type(str_1))
# Присваиваем литерал строки в двойных кавычках.
str_2 = "Я – строка в двойных кавычках."
# Тип str_2: <class 'str'>.
print('Тип str_2:', type(str_2))
# Используем три двойные кавычки.
str_3 = """Я – строка в тройных кавычках.
Я могу располагаться на нескольких строках."""
# Тип str_3: <class 'str'>.
print('Тип str_3:', type(str_3))
# Используем три одинарные кавычки.
str_4 = '''Я тоже строка в тройных кавычках.
Но на этот раз были использованы три одинарные кавычки.'''
# Тип str_4: <class 'str'>.
print('Тип str_4:', type(str_4))
Тип str_1: <class 'str'>
Тип str_2: <class 'str'>
Тип str_3: <class 'str'>
Тип str_4: <class 'str'>
Пример №1. Создание литералов строк в Python.
Использование для создания строк сразу нескольких видов кавычек обусловлено тем, что это дает возможность использовать в литералах, заключенных в кавычки одного типа, кавычки другого типа (см. пример №2). При этом допускается использование кавычек любого разрешенного типа внутри строковых литералов, заключенных в кавычки того же типа, предварительно экранировав их при помощи обратного слеша \.
# Используем одинарные кавычки внутри двойных.
str_1 = "Пример 'одинарных' кавычек внутри двойных."
# Выводим строку на экран.
print(str_1, end='\n\n')
# Используем двойные кавычки внутри одинарных.
str_2 = 'Пример "двойных" кавычек внутри одинарных.'
# Выводим строку на экран.
print(str_2, end='\n\n')
# Двойные, одинарные и тройные одинарные внутри тройных.
str_3 = """Вот 'одинарные', вот "двойные", а вот и
'''тройные одинарные''' кавычки внутри тройных."""
# Выводим строку на экран.
print(str_3, end='\n\n')
# Используем одинарные кавычки внутри одинарных.
str_4 = 'Пример \'одинарных\' кавычек внутри одинарных.'
# Выводим строку на экран.
print(str_4, end='\n\n')
# Слэшем экранируем и другие виды однотипных кавычек.
str_5 = """Пример \"\"\"тройных\"\"\" внутри тройных."""
# Выводим строку на экран.
print(str_5, end='\n\n')
Пример 'одинарных' кавычек внутри двойных.
Пример "двойных" кавычек внутри одинарных.
Вот 'одинарные', вот "двойные", а вот и
'''тройные одинарные''' кавычки внутри тройных.
Пример 'одинарных' кавычек внутри одинарных.
Пример """тройных""" внутри тройных.
Пример №2. Порядок использования кавычек внутри строк.
Если строковый литерал получается довольно длинным, возникает необходимость в его переносе на другую строку программного кода. Сделать это можно несколькими способами, например:
- использовать обратный слеш \ в требуемом месте переноса строки;
- использовать строки в тройных кавычках, которые как раз и предназначены для оформления больших блоков текста внутри исходного кода;
- разбить строку на несколько частей и затем объединить их при помощи символа +, при этом не забыв использовать круглые скобки, как показано в примере №3.
# Используем обратный слеш для переноса строки.
str_1 = "Очень длинные блоки текста можно переносить \
на новую строку \nпри помощи обратного слеша."
# Выводим строку на экран.
print(str_1, end='\n\n')
# Используем для блоков текста тройные кавычки.
str_2 = """Наиболее удобный способ размещения
больших блоков текста сразу на нескольких строках –
это использование тройных кавычек."""
# Выводим строку на экран.
print(str_2, end='\n\n')
# Также строки можно переносить при помощи
# круглых скобок и знака +.
str_3 = ('Одна ' +
'объединенная ' +
'строка.')
# Выводим строку на экран.
print(str_3)
Очень длинные блоки текста можно переносить на новую строку
при помощи обратного слеша.
Наиболее удобный способ размещения
больших блоков текста сразу на нескольких строках –
это использование тройных кавычек.
Одна объединенная строка.
Пример №3. Использование многострочных блоков текста в коде.
О круглых скобках мы уже говорили раньше, их можно использовать для того, чтобы расположить длинную инструкцию на нескольких строках. В нашем случае такой инструкцией является объединение строки (конкатенация) при помощи оператора сложения. Подробнее об этом мы поговорим чуть ниже.
Экранированные последовательности в Python
Не каждый символ можно свободно отобразить внутри строкового литерала. Поэтому в Python, как и во многих других языках программирования, имеется специальный набор экранированных (управляющих) последовательностей.
Экранированная последовательность – это специальная последовательность символов, начинающаяся со знака обратного слеша, которая обозначает символ, не всегда представимый внутри строки другими способами.
Перечислим использующиеся в Python экранированные последовательности:
- \0 – символ Null (не является признаком конца строки);
- \a – звонок;
- \b – забой, т.е. возврат на одну позицию (\u0008);
- \v – вертикальная табуляция (\u000B);
- \t – горизонтальная табуляция (\u0009);
- \n – перевод строки (\u000A);
- \f – подача страницы, т.е. ее очистка;
- \r – возврат каретки (\u000D);
- \" – двойная кавычка (\u0022);
- \' – одинарная кавычка (\u0027);
- \\ – обратный слеш (\u005C);
- \ooo – восьмеричный код символа (не более трех цифр);
- \xhh – символ Latin-1, заданный двумя цифрами в шестнадцатеричной системе счисления;
- \N{id} – идентификатор ID базы данных Юникода (т.е. название символа в базе);
- \uhhhh – 16-битный символ Юникода, заданный четырьмя цифрами в шестнадцатеричной системе счисления;
- \uhhhhhhhh – 32-битный символ Юникода в шестнадцатеричном представлении;
- \другое – не является экранированной последовательностью (символ обратного слеша сохраняется).
Использование некоторых управляющих последовательностей показано в примере №4.
# Используем символы перевода строки
# и горизонтальной табуляции.
str_1 = '1-я строка.\n2-я \t\t строка.'
# Выводим строку на экран.
print(str_1, end='\n\n')
# Тоже самое, но при помощи символов Юникода.
str_2 = '1-я строка.\u000A2-я \u0009\u0009 строка.'
# Выводим строку на экран.
print(str_2, end='\n\n')
# Используем название символа Юникода.
str_3 = 'Символ \N{LATIN SMALL LETTER A}'
# Выводим строку на экран.
print(str_3, end='\n\n')
# Здесь экранированная последовательность отсутствует.
str_4 = 'Обратный слеш \ничего не экранирует.'
# Выводим строку на экран.
print(str_4)
1-я строка.
2-я строка.
1-я строка.
2-я строка.
Символ a
Обратный слеш \ничего не экранирует.
Пример №4. Использование экранированных последовательностей в строках.
Использовав кнопку «Результат» (как и всегда, когда она присутствует в блоке), мы увидим, что вывод первых двух строк на экран будет совершенно идентичным, т.к. экранированные последовательности представляют собой символы Юникода. Кроме того, в последней строке обратный слеш ничего не экранирует, ведь после него не стоят символы какой-нибудь управляющей последовательности.
Бывают случаи, когда нужно подстраховаться и запретить экранированные последовательности в строке. Хорошим примером может служить строка с адресом, например, 'D:\python\new_tests\test_1.py'. В таких ситуациях перед строкой нужно использовать символ r, который отключает для строки механизм экранирования (см. пример №5).
# Ничего не предпринимаем.
str_1 = 'D:\python\new_tests\test_1.py'
# Выводим свой косяк на экран.
print(str_1, end='\n\n')
# Подавляем механизм экранирования, используя сырую строку.
str_2 = r'D:\python\new_tests\test_1.py'
# Выводим строку на экран.
print(str_2, end='\n\n')
# Или экранируем сами слеши.
str_3 = 'D:\\python\\new_tests\\test_1.py'
# Выводим строку на экран.
print(str_3, end='\n\n')
D:\python
ew_tests est_1.py
D:\python\new_tests\test_1.py
D:\python\new_tests\test_1.py
Пример №5. Подавление экранирования в строках.
Как видим, в нашем случае последовательность \n интерпретируется как символ новой строки, а последовательность \t замещается символом горизонтальной табуляции. Ситуация исправляется либо за счет использования неформатированной строки, либо экранированием обратных слешей.
Cледует добавить, что строки (даже «сырые») не могут заканчиваться неэкранированным символом обратного слеша, т.к. он будет экранировать кавычки в конце строки. В таких случаях можно добавить его отдельно при помощи конкатенации (например, r'D:\text' + '\\'), продублировать и затем удалить при помощи среза (например, r'D:\text\\'[:-1]) или не использовать подавление вообще, экранировав все слеши в обычной строке (например, 'D:\\text\\').
Доступ по индексу и срезы строк в Python
Как говорилось выше, строки в Python представляют собой неизменяемые упорядоченные последовательности символов Юникода. И хотя изменить строку нельзя, доступ к ее отдельным символам можно получить при помощи операции индексирования. Для этого нужно указать в квадратных скобках после имени или литерала строки порядковый номер символа в последовательности, не забывая, что нумерация символов в строке начинается с нуля (см. пример №6).
# Формируем строку.
str_1 = 'строка'
# Выводим 1-й символ (нумерация начинается с нуля).
print('str_1[0] ->', str_1[0], end='\n\n')
# Выводим последний символ (длина строки минус один).
print('str_1[len(str_1)-1] ->', str_1[len(str_1)-1], end='\n\n')
# Можно использовать отрицательные индексы, тогда
# нумерация будет идти с конца и начинаться с -1.
print('str_1[-1] ->', str_1[-1], end='\n\n')
str_1[0] -> с
str_1[len(str_1)-1] -> а
str_1[-1] -> а
Пример №6. Доступ к символам строки по индексу.
В отличие от многих других языков программирования в Python доступ к символам строки возможен также и по отрицательным индексам. В этом случае можно считать, что отсчет ведется с конца строки и начинается с -1. Более того, в Python для строк (и других упорядоченных последовательностей) доступна операция извлечения среза, которая без особых усилий позволяет извлекать не только отдельные символы, но и целые диапазоны символов, не прибегая при этом к специальным методам или встроенным функциям (см. пример №7).
# Формируем строку.
str_1 = 'Один, два, три.'
# Выводим первые два символа.
print('str_1[0:2] ->', str_1[0:2], end='\n\n')
# Можно и так.
print('str_1[:2] ->', str_1[:2], end='\n\n')
# Выводим последние два символа.
print('str_1[-2:] ->', str_1[-2:], end='\n\n')
# Выводим символы с 3-го по 7-й.
print('str_1[2:7] ->', str_1[2:7], end='\n\n')
# Используем отрицательные индексы.
print('str_1[-7:-2] ->', str_1[-7:-2], end='\n\n')
# Получим поверхностную копию строки.
print('str_1[:] ->', str_1[:], end='\n\n')
str_1[0:2] -> Од
str_1[:2] -> Од
str_1[-2:] -> и.
str_1[2:7] -> ин, д
str_1[-7:-2] -> а, тр
str_1[:] -> Один, два, три.
Пример №7. Порядок извлечения срезов строк.
При извлечении срезов следует помнить, что нумерация символов в строках начинается с нуля, а символ с индексом второго предела, указанного в квадратных скобках, не будет присутствовать в срезе. Например, в срезе str_1[0:5] будут присутствовать первые пять символов с индексами от 0 до 4, но не включая символ с индексом 5.
Добавим, что один или оба предела среза можно опускать. Если не указывать первый предел, интерпретатор будет начинать срез с первого символа строки (с индексом 0). При отсутствии второго предела срез будет идти до конца строки. Если опустить оба предела, мы получим копию строки от первого до последнего символа. Более того, при необходимости разрешается указывать и третий предел, который будет задавать шаг среза (см. пример №8).
# Формируем строку.
str_1 = 'Вместе весело шагать...'
# Выводим ее для наглядности.
print('str_1 ->', str_1, end='\n\n')
# Выводим каждый 2-й символ среза (слева направо).
print('str_1[0:10:2] ->', str_1[0:10:2], end='\n\n')
# Можно и так.
print('str_1[:10:2] ->', str_1[:10:2], end='\n\n')
# Выводим каждый третий символ всей строки.
print('str_1[::3] ->', str_1[::3], end='\n\n')
# Выводим каждый 2-й, считая с конца среза (-1, -2,...).
# Сам срез берется справа налево, если шаг отрицательный.
print('str_1[12:2:-2] ->', str_1[12:2:-2], end='\n\n')
# Выводим каждый 3-й символ среза, считая справа налево.
print('str_1[-15:3:-3] ->', str_1[-15:3:-3], end='\n\n')
# Выводим каждый 2-й символ, считая с конца строки.
print('str_1[::-2] ->', str_1[::-2])
str_1 -> Вместе весело шагать...
str_1[0:10:2] -> Вет е
str_1[:10:2] -> Вет е
str_1[::3] -> Вс соат.
str_1[12:2:-2] -> оее т
str_1[-15:3:-3] -> ее
str_1[::-2] -> ..тгшоее теВ
Пример №8. Порядок использования шага среза у строк.
Как видим, шаг среза также может иметь отрицательное значение. В этом случае отсчет символов и шагов ведется в противоположном направлении, а границы среза указываются справа налево, т.е. индекс символа, стоящего правее в последовательности должен указываться первым. Например, в срезе примера str_1[-15:3:-3] отсчет ведется справа налево, начиная с 15-го символа, отсчитываемого с конца строки, до символа с индексом 3, который находится левее и в срез не включается.
В конце добавим, что к классу упорядоченных последовательностей относятся не только строки, но также списки и кортежи, которые мы будем изучать следующими. Для них операции индексирования и среза имеют практически тот же порядок, что и для строк, делая их не только удобными, но и весьма универсальными инструментами обработки упорядоченных последовательностей.
Операторы строк в Python
С оператором сложения + применительно к строкам мы уже познакомились выше. Он используется для объединения строк в одну. Соответственно комбинированный оператор += добавляет целевую строку в конец текущей. Еще одним арифметическим оператором, который применим к строкам, является оператор умножения * (соответствующий ему комбинированный оператор имеет вид *=). Однако в отличие от чисел здесь он служит для повторения строки указанное число раз (см. пример №9).
# Формируем строки.
str_1 = 'один '
str_2 = 'два'
str_3 = '-'
# Осуществляем конкатенацию строк (т.е. объединение).
print('str_1 + str_2 ->', str_1 + str_2, end='\n\n')
# Повторяем строку 3 раза (str_1 + str_1 + str_1).
print('str_1*3 ->', str_1*3, end='\n\n')
# Заносим в переменную объединение строк str_1 и str_2.
str_1 += str_2
# Теперь в str_1 хранится строка 'один два'.
print('str_1 ->', str_1, end='\n\n')
# Умножением удобно выводить повторяющиеся символы.
str_3 *= 10
# Теперь str_3 равна 10-ти дефисам.
print('str_3 *= 10 ->', str_3)
str_1 + str_2 -> один два
str_1*3 -> один один один
str_1 += str_2 -> один два
str_3 *= 10 -> ----------
Пример №9. Использование операторов + и * применительно к строкам.
Следует помнить, что смешивать числа и строки в выражениях сложения нельзя, т.к. интерпретатор не занимается автоматическим приведением типов и просто выдаст ошибку.
Теперь давайте познакомимся с оператором проверки на вхождение in, который применительно к строкам совершает поиск требуемой подстроки (левый операнд) в целевой строке (правый операнд). В случае успеха операция возвращает True, иначе – False (см. пример №10).
# Формируем строки.
str_1 = 'Два слова.'
str_2 = 'слова'
# Проверяем наличие символа в первой строке.
answer = 'л' in str_1
# Если операция вернула True,
if answer:
# выводим подтверждение на экран.
print('Буква \'л\' присутствует в строке str_1.', end='\n\n')
# Иначе
else:
# выводим на экран отрицание.
print('Буквы \'л\' нет в строке str_1.', end='\n\n')
# Проверяем вхождение str_2 в str_1, используя not in.
if str_2 not in str_1:
# Выводим подтверждение на экран.
print('str_2 отсутствует в str_1.')
# Иначе
else:
# выводим на экран сообщение.
print('str_2 присутствует в str_1.')
Буква 'л' присутствует в строке str_1.
str_2 присутствует в str_1.
Пример №10. Использование оператора in применительно к строкам.
Как видно из примера, оператор in может использоваться не только самостоятельно, но и совместно с оператором отрицания not, который инверсирует возвращаемое логическое значение оператора in. Например, операция 'ли' not in 'Питон' вернет True вместо False.
Забегая вперед добавим, что оператор in входит также и в состав инструкции цикла for, который обычно используется, когда возникает необходимость в обходе, например, всех элементов последовательности или атрибутов объекта. Синтаксис цикла for в Python имеет следующий вид:
for <Переменная> in <Итерируемый объект>:
<Тело цикла>
else:
<Дополнительный блок инструкций>
В ходе выполнения цикла for интерпретатор один за другим присваивает переменной заголовка элементы объекта и выполняет для них инструкции тела цикла (см. пример №11). Если цикл нужно прервать, используется инструкция break, которая передает управление инструкции, следующей сразу за циклом. Кроме того, в цикле for разрешается использовать необязательный блок else, инструкции которого выполняются только после удачного завершения цикла (т.е. при отсутствии ошибки или прерывания за счет использования инструкции break).
# Формируем строку.
str_1 = 'Весенний карнавал.'
# Количество букв будем хранить в счетчике.
n = 0
# Посчитаем количество букв 'а' в строке.
for let in str_1:
# Если очередной символ строки наша буква,
if let == 'а':
# увеличиваем счетчик на 1.
n += 1
# Выводим полученное количество на экран.
print("Количество букв 'а' в строке:", n)
Количество букв 'а' в строке: 3
Пример №11. Использование цикла for для обхода символов строки.
Функции и методы строк в Python
Помимо операции среза, перечисленых операторов и цикла for язык Python предоставляет для обработки строк богатый набор методов класса str и несколько встроенных функций. Перечислим основные из них.
- str.capitalize() – возвращает копию строки, переводя первый символ строки в верхний регистр, а все остальные в нижний (см. пример №12).
- str.title() – возвращает копию строки, в которой первые символы каждого слова преобразованы в символы верхнего регистра, а все остальные символы – в символы нижнего регистра.
- str.upper() – возвращает копию строки, в которой все символы приведены к верхнему регистру.
- str.lower() – возвращает копию строки, в которой все символы приведены к нижнему регистру.
- str.swapcase() – возвращает копию строки, в которой все символы верхнего регистра преобразованы в символы нижнего регистра, а все символы нижнего регистра – в символы верхнего регистра.
# str.capitalize().
str_1 = "сиНий Кит".capitalize()
# Синий кит.
print('"сиНий Кит".capitalize() ->', str_1, end='\n\n')
# str.title().
str_2 = "сиНий Кит".title()
# Синий Кит.
print('"сиНий Кит".title() ->', str_2, end='\n\n')
# str.upper().
str_3 = "сиНий Кит".upper()
# СИНИЙ КИТ.
print('"сиНий Кит".upper() ->', str_3, end='\n\n')
# str.lower().
str_4 = "сиНий Кит".lower()
# синий кит.
print('"сиНий Кит".lower() ->', str_4, end='\n\n')
# str.swapcase().
str_5 = "сиНий Кит".swapcase()
# СИнИЙ кИТ.
print('"сиНий Кит".swapcase() ->', str_5)
"сиНий Кит".capitalize() -> Синий кит
"сиНий Кит".title() -> Синий Кит
"сиНий Кит".upper() -> СИНИЙ КИТ
"сиНий Кит".lower() -> синий кит
"сиНий Кит".swapcase() -> СИнИЙ кИТ
Пример №12. Методы строк (часть 1).
- str.count(sub[, start[, end]]) – возвращает число вхождений подстроки sub в строку str или в срез строки str[start:end], если он задан (см. пример №13). При этом подсчитываются только непересекающиеся последовательности символов, т.е. в строке aaaa будет найдено всего две строки aa.
- str.find(sub[, start[, end]]) – возвращает индекс первого вхождения подстроки sub в строку str или в срез строки str[start:end], если он задан. В случае неудачного поиска метод возвращает -1. Обратите внимание, что при использовании среза отсчет индекса искомой подстроки все равно отсчитывается от начала всей строки (тоже самое касается и аналогичных методов ниже).
- str.index(sub[, start[, end]]) – также возвращает индекс первого вхождения подстроки sub в строку str или в срез строки str[start:end], если он задан. Однако в случае неудачного поиска метод вызывает исключение ValueError.
- str.rfind(sub[, start[, end]]) – возвращает индекс последнего вхождения подстроки sub в строку str или в срез строки str[start:end], если он задан. В случае неудачного поиска метод возвращает -1.
- str.rindex(sub[, start[, end]]) – также возвращает индекс последнего вхождения подстроки sub в строку str или в срез строки str[start:end], если он задан. Однако в случае неудачного поиска метод вызывает исключение ValueError.
# str.count(sub[, start[, end]]).
# Получим 1.
ans = "Синий иней".count('н', 2, 5)
print('"Синий иней".count("н", 2, 5) ->', ans)
# Получим 0.
ans = "Синий иней".count('s')
print('"Синий иней".count("s") ->', ans, end='\n\n')
# str.find(sub[, start[, end]]).
# Получим 3.
ans = "Синий иней".find('и', 2, 5)
print('"Синий иней".find("и", 2, 5) ->', ans)
# Получим -1 (регистр важен).
ans = "Синий иней".find('И')
print('"Синий иней".find("И") ->', ans, end='\n\n')
# str.index(sub[, start[, end]]).
# Получим 3.
ans = "Синий иней".index('и', 2, 5)
print('"Синий иней".index("и", 2, 5) ->', ans)
# substring not found.
ans = "Синий иней".index('И')
print('"Синий иней".index("И") ->', ans, end='\n\n')
"Синий иней".count("н", 2, 5) -> 1
"Синий иней".count("s") -> 0
"Синий иней".find("и", 2, 5) -> 3
"Синий иней".find("И") -> -1
"Синий иней".index("и", 2, 5) -> 3
substring not found
Пример №13. Методы строк (часть 2).
- str.ljust(width[, fillchar]) – возвращает копию строки, выровненную по левому краю в строке с длиной width. Недостающие символы по умолчанию заполняются пробелами или символом fillchar, если данный необязательный аргумент будет задан. Кроме того, если width < len(str), то будет возвращена копия исходной строки без каких-либо изменений (см. пример №14).
- str.rjust(width[, fillchar]) – возвращает копию строки, выровненную по правому краю в строке с длиной width. Недостающие символы по умолчанию заполняются пробелами или символом fillchar, если данный необязательный аргумент будет задан. Кроме того, если width < len(str), то будет возвращена копия исходной строки без каких-либо изменений.
- str.center(width[, fillchar]) – возвращает копию строки, отцентрированную в строке с длиной width. Недостающие символы по умолчанию заполняются пробелами или символом fillchar, если данный необязательный аргумент будет задан. Кроме того, если width < len(str), то будет возвращена копия исходной строки без каких-либо изменений.
- str.expandtabs(tabsize=8) – возвращает копию строки, в которой символы табуляции замещены пробелами с шагом 8 (по умолчанию) или в соответствии со значением необязательного аргумента tabsize. Если какая-то подстрока не помещается внутри одного столбца, то ширина данного столбца будет увеличена до необходимых размеров.
- str.zfill(width) – возвращает копию строки, в которой исходная строка str дополняется нулями слева так, чтобы длина новой строки стала равна width.
# str.ljust(width[, fillchar]).
str_1 = "Синий иней".ljust(15, ".")
# Синий иней.....
print('"Синий иней".ljust(15, ".") ->', str_1, end='\n\n')
# str.rjust(width[, fillchar])
str_2 = "Синий иней".rjust(15, ".")
# .....Синий иней
print('"Синий иней".rjust(15, ".") ->', str_2, end='\n\n')
# str.center(width[, fillchar])
str_3 = "Синий иней".center(15, ".")
# ...Синий иней..
print('"Синий иней".center(15, ".") ->', str_3, end='\n\n')
# str.zfill(width)
str_4 = "Синий иней".zfill(15)
# 00000Синий иней
print('"Синий иней".zfill(15) ->', str_4, end='\n\n')
# str.expandtabs(tabsize=8)
# 0 1 22 333 4444 55555 666666
str_5 = "0\t1\t22\t333\t4444\t55555\t666666".expandtabs(4)
print(str_5, end='\n\n')
# 0 1 22 333 4444 55555 666666
str_5 = "0\t1\t22\t333\t4444\t55555\t666666".expandtabs(2)
print(str_5)
"Синий иней".ljust(15, ".") -> Синий иней.....
"Синий иней".rjust(15, ".") -> .....Синий иней
"Синий иней".center(15, ".") -> ...Синий иней..
"Синий иней".zfill(15) -> 00000Синий иней
0 1 22 333 4444 55555 666666
0 1 22 333 4444 55555 666666
Пример №14. Методы строк (часть 3).
- str.replace(old, new[, count]) – возвращает копию строки, в которой все подстроки old заменены на подстроки new. Если указан аргумент count, метод производит только указанное количество замен (см. пример №15).
- str.strip([chars]) – возвращает копию строки, из которой удалены начальные и завершающие пробельные символы (по умолчанию) или символы, входящие в строку chars.
- str.lstrip([chars]) – возвращает копию строки, из которой удалены начальные пробельные символы (по умолчанию) или символы, входящие в строку chars.
- str.rstrip([chars]) – возвращает копию строки, из которой удалены завершающие пробельные символы (по умолчанию) или символы, входящие в строку chars.
# str.replace(old, new[, count]).
# Синий кит.
str_1 = "Синий иней".replace("иней", "кит")
print('"Синий иней".replace("иней", "кит") ->', str_1)
# Синий *ней.
str_2 = "С*н*й *ней".replace("*", "и", 2)
print('"С*н*й *ней".replace("*", "и", 2) ->', str_2, end='\n\n')
# str.strip([chars])
str_3 = "Синий иней".strip("Сийк")
# ний ине.
print('"Синий иней".strip("Сийк") ->', str_3, end='\n\n')
# str.lstrip([chars])
str_4 = "Синий иней".lstrip("Сийк")
# ний иней.
print('"Синий иней".lstrip("Сийк") ->', str_4, end='\n\n')
# str.rstrip([chars])
str_5 = "Синий иней".rstrip("Сийк")
# Синий ине.
print('"Синий иней".rstrip("Сийк") ->', str_5)
"Синий иней".replace("иней", "кит") -> Синий кит
"С*н*й *ней".replace("*", "и", 2) -> Синий *ней
"Синий иней".strip("Сийк") -> ний ине
"Синий иней".lstrip("Сийк") -> ний иней
"Синий иней".rstrip("Сийк") -> Синий ине
Пример №15. Методы строк (часть 4).
- str.split(sep=None, maxsplit=-1) – выполняет разбиение исходной строки на подстроки по пробельным символам (по умолчанию) или подстроке sep, если она задана, и возвращает их в виде списка. Следует добавить, что когда аргумент sep не указывается, интерпретатор считает все подряд идущие пробельные символы одним пробелом, а разбиение пустой строки или строки, состоящей из одних пробельных символов, возвращает пустой список. Однако, если разбить пустую строку, использовав отличный от пробела разделитель, метод вернет список с пустой строкой (см. пример №16). Если указан аргумент maxsplit, метод производит только указанное количество разбиений, которые будут выполнены слева направо. По умолчанию строка разбивается по всем имеющимся разделителям.
- str.rsplit(sep=None, maxsplit=-1) – тоже самое, что и предыдущий метод. Однако в этом случае разбиение выполняется с конца строки, т.е. справа налево.
- str.splitlines([keepends]) – возвращает список строк, выполняя разбиение строки по символам перевода строки и по умолчанию удаляя их. Однако, если указать необязательный аргумент keepends=True, символы перевода строки будут сохранены. К допустимым символам перевода строки относятся: \n – перенос строки, \r – возврат каретки, \r\n – возврат каретки и перенос строки, \v или \x0b – вертикальный отступ, \f или \x0c – разрыв страницы, \x1c – разделитель файлов, \x1d – разделитель групп, \x1e – разделитель строк, \x85 – следующая строка, \u2028 – разделитель строк, \u2029 – разделитель абзацев.
- str.partition(sep) – разбивает строку в направлении слева направо по первому найденному разделителю sep и возвращает кортеж из трех элементов: строка до разделителя, сам разделитель и строка после разделителя. Если разделитель найден не будет, метод вернет кортеж так же состоящий из трех элементов: исходная строка str и две пустые строки.
- str.rpartition(sep) – разбивает строку в направлении справа налево (т.е. поиск разделителя ведется с конца строки) по первому с конца разделителю sep и возвращает кортеж из трех элементов: строка до разделителя, сам разделитель и строка после разделителя. Если разделитель найден не будет, метод вернет кортеж так же состоящий из трех элементов: две пустые строки, а также сама исходная строка str.
- str.join(iterable) – возвращает строку, полученную объединением всех элементов итерируемого (т.е. элементы которого можно пересчитать) объекта iterable через разделитель str, который может быть пустой строкой. Отметим, все элементы передаваемой последовательности должны быть строками, иначе будет вызвана ошибка.
# str.split(sep=None, maxsplit=-1).
str_1 = "Синий иней".split()
# ['Синий', 'иней'].
print('"Синий иней".split() ->', str_1)
str_2 = "Синий \\t\\v иней".split()
# ['Синий', 'иней'].
print('"Синий иней".split() ->', str_2)
str_3 = "".split()
# Пустой список, т.е. [].
print('"".split() ->', str_3)
str_4 = "".split(",")
# Список с пустой строкой, т.е. [''].
print('"".split(",") ->', str_4)
str_5 = "Синий иней".split("и")
# ['С', 'н', 'й ', 'ней'].
print('"Синий иней".split("и") ->', str_5)
str_6 = "Синий иней".split("и", 2)
# ['С', 'н', 'й иней'].
print('"Синий иней".split("и", 2) ->', str_6, end='\n\n')
# str.splitlines([keepends]).
str_7 = "Синий\nиней".splitlines()
# ['Синий', 'иней'].
print('"Синий\\nиней".splitlines() ->', str_7)
# Оставим символ перевода строки.
str_8 = "Синий\nиней".splitlines(True)
# ['Синий\n', 'иней'].
print('"Синий\\nиней".splitlines(True) ->', str_8, end='\n\n')
# str.partition(sep).
str_9 = "Синий иней".partition("и")
# ('С', 'и', 'ний иней').
print('"Синий иней".partition("и") ->', str_9, end='\n\n')
# str.rpartition(sep).
str_10 = "Синий иней".rpartition("и")
# ('Синий ', 'и', 'ней').
print('"Синий иней".rpartition("и") ->', str_10, end='\n\n')
# str.join(iterable).
str_11 = "".join(["У", "х"])
# Ух.
print('"".join(["У", "х"]) ->', str_11)
str_12 = "л".join(["и", "и"])
# или.
print('"л".join(["и", "и"]) ->', str_12, end='\n\n')
# Не забываем про кнопку «Результат».
"Синий иней".split() -> ['Синий', 'иней']
"Синий \t\v иней".split() -> ['Синий', 'иней']
"".split() -> []
"".split(",") -> ['']
"Синий иней".split("и") -> ['С', 'н', 'й ', 'ней']
"Синий иней".split("и", 2) -> ['С', 'н', 'й иней']
"Синий\nиней".splitlines() -> ['Синий', 'иней']
"Синий\nиней".splitlines(True) -> ['Синий\n', 'иней']
"Синий иней".partition("и") -> ('С', 'и', 'ний иней')
"Синий иней".rpartition("и") -> ('Синий ', 'и', 'ней')
"".join(["У", "х"]) -> Ух
"л".join(["и", "и"]) -> или
Пример №16. Методы строк (часть 5).
- str.startswith(prefix[, start[, end]]) – возвращает True, если строка str или срез строки str[start:end], если он задан, начинается последовательностью символов prefix. В противном случае метод возвращает False (см. пример №17).
- str.endswith(suffix[, start[, end]]) – возвращает True, если строка str или срез строки str[start:end], если он задан, заканчивается последовательностью символов suffix. В противном случае метод возвращает False.
- str.isidentifier() – возвращает True, если строка str не пустая и является допустимым идентификатором. В противном случае метод возвращает False.
- str.isspace() – возвращает True, если строка str не пустая и состоит только из пробельных символов. В противном случае метод возвращает False.
- str.isascii() – возвращает True, если строка str не пустая и содержит только символы ASCII. В противном случае метод возвращает False.
- str.isdigit() – возвращает True, если строка str не пустая и содержит только символы ASCII, обозначающие цифры десятичной системы счисления. В противном случае метод возвращает False.
- str.isalpha() – возвращает True, если строка str не пустая и состоит только из алфавитных символов Юникода. В противном случае метод возвращает False.
- str.isdecimal() – возвращает True, если строка str не пустая и содержит только символы Юникода, обозначающие цифры десятичной системы счисления. В противном случае метод возвращает False.
- str.isnumeric() – возвращает True, если строка str не пустая и состоит только из символов Юникода, которые используются для обозначения цифр (не только десятичной системы счисления). В противном случае метод возвращает False.
- str.isalnum() – возвращает True, если строка str не пустая и состоит только из алфавитных символов и символов Юникода, которые используются для обозначения цифр (не только десятичной системы счисления). В противном случае метод возвращает False.
- str.isprintable() – возвращает True, если строка str пустая или содержит только печатаемые символы, включая пробел, но не символ перевода строки. В противном случае метод возвращает False.
- str.istitle() – возвращает True, если строка str не пустая и при этом имеет формат строки заголовка. В противном случае метод возвращает False.
- str.islower() – возвращает True, если строка str имеет хотя бы один символ, который может быть представлен в нижнем регистре, и все такие символы находятся в нижнем регистре. В противном случае метод возвращает False.
- str.isupper() – возвращает True, если строка str имеет хотя бы один символ, который может быть представлен в верхнем регистре, и все такие символы находятся в верхнем регистре. В противном случае метод возвращает False.
- str.encode(encoding='utf-8', errors='strict') – возвращает новую строку типа bytes в кодировке utf-8 (по умолчанию) или в кодировке, определяемой аргументом encoding. Параметр errors определяет порядок обработки ошибок в процессе кодировки (см. подраздел «Error Handlers» в подразделе «codecs — Codec registry and base classes» раздела «Binary Data Services» стандартной библиотеки).
# str.startswith(prefix[, start[, end]]).
str_1 = "Синий иней".startswith("Си")
# True.
print('"Синий иней".startswith("Си") ->', str_1, end='\n\n')
# str.endswith(suffix[, start[, end]]).
str_2 = "Синий иней".endswith("ку", 2, 8)
# False.
print('"Синий иней".endswith("ку", 2, 8) ->', str_2, end='\n\n')
# str.isidentifier().
str_3 = "Синий".isidentifier()
# True.
print('"Синий".isidentifier() ->', str_3, end='\n\n')
# str.isspace().
str_4 = "Синий".isspace()
# False.
print('"Синий".isspace() ->', str_4, end='\n\n')
# str.isalpha().
str_5 = "Синий".isalpha()
# True.
print('"Синий".isalpha() ->', str_5, end='\n\n')
# str.isprintable().
str_6 = "Синий".isprintable()
# True.
print('"Синий".isprintable() ->', str_6, end='\n\n')
# str.islower().
str_7 = "Синий".islower()
# False.
print('"Синий".islower() ->', str_7, end='\n\n')
# str.isdecimal().
str_8 = "125".isdecimal()
# True.
print('"125".isdecimal() ->', str_8, end='\n\n')
str_9 = "12.5".isdecimal()
# Точка не является цифрой 10-й СС (False).
print('"12.5".isdecimal() ->', str_9, end='\n\n')
str_10 = "\u17e1\u17e2".isdecimal()
# Цифры 10-й СС в кхмерском языке (True).
print('"\u17e1\u17e2".isdecimal() ->', str_10, end='\n\n')
str_11 = "\u00b2".isdecimal()
# Символ квадрата не является цифрой 10-й СС (False).
print('"\u00b2".isdecimal() ->', str_11, end='\n\n')
# str.isnumeric().
str_12 = "\u00b2".isnumeric()
# Но к цифрам символ квадрата относится (True).
print('"\u00b2".isnumeric() ->', str_12, end='\n\n')
# str.isalnum().
str_13 = "кит2".isalnum()
# True.
print('"кит2".isalnum() ->', str_13, end='\n\n')
"Синий иней".startswith("Си") -> True
"Синий иней".endswith("ку", 2, 8) -> False
"Синий".isidentifier() -> True
"Синий".isspace() -> False
"Синий".isalpha() -> True
"Синий".isprintable() -> True
"Синий".islower() -> False
"125".isdecimal() -> True
"12.5".isdecimal() -> False
"១២".isdecimal() -> True
"²".isdecimal() -> False
"²".isnumeric() -> True
"кит2".isalnum() -> True
Пример №17. Методы строк (часть 6).
- len(str) – встроенная функция, которая применительно к строкам возвращает длину строки, т.е. количество символов в ней (см. пример №18).
- ord(c) – встроенная функция, которая возвращает порядковый номер символа Юникода переданного в качестве аргумента c.
- chr(i) – встроенная функция, которая возвращает символ Юникода, номер которого равен значению аргумента i.
Как видим, для строк в Python предусмотрен действительно широкий арсенал методов. При чем некоторые из них мы здесь даже не упоминали. Однако это всего лишь пару методов, которые с легкостью можно найти в стандартной библиотеке в подразделе «Text Sequence Type — str» раздела «Built-in types».
Стоит добавить, если возможностей встроенных функций или методов типов не хватает, всегда можно создать свою собственную функцию. Делается это при помощи инструкции def, которая имеет следующий формат:
def <Имя функции>(arg_1, arg_2, ..., arg_n):
<Тело функции>
return <Возвращаемое значение>
В определении заголовка функции передаваемые аргументы перечисляются через запятую. При этом разрешается присваивать аргументам значения, которые будут использоваться, как значения по умолчанию, если при вызове функции будет передано меньшее количество аргументов. Тело функции представляет собой обычный программный код, который будет выполняться каждый раз при вызове функции. Вызов функции осуществляется при помощи имени функции и круглых скобок с передаваемыми функции значениями аргументов, которые также должны перечисляться через запятую (см. пример №19). Если аргументы передаются без имен, их называют позиционными, т.к. интерпретатор сопоставляет их с порядком следования в заголовке определения функции. Кроме того, имеется возможность передавать функциям аргументы, явно указывая их имена и значения. Такие аргументы называются именованными и могут передаваться функции в любом порядке, но только после позиционных аргументов, если такие присутствуют в вызове функции. Необязательная инструкция return возвращает результат вызывающей программе в месте вызова функции.
# Определим собственную функцию.
def pow_func(x, y=2):
# Возводим x в степень y.
p = x**y
# Возвращаем результат вызывающей программе.
return p
# Вызываем функцию и сохраняем результат в переменной.
res_1 = pow_func(3, 3)
# Получим 27, т.е. 3 в кубе.
print('pow_func(3, 3) ->', res_1, end='\n\n')
# Второй аргумент указывать не будем.
res_2 = pow_func(4)
# Выведет 16, т.е. 4 в квадрате.
print('pow_func(4) ->', res_2, end='\n\n')
# Явно указываем имена аргументов, поэтому порядок не важен.
res_3 = pow_func(y=5, x=2)
# Получим 32, т.е. 2 в 5 степени.
print('pow_func(y=5, x=2) ->', res_3)
pow_func(3, 3) -> 27
pow_func(4) -> 16
pow_func(y=5, x=2) -> 32
Пример №19. Создание пользовательской функции.
Предоставленной здесь информации нам вполне хватит, чтобы писать простейшие функции. Но к ним мы еще обязательно вернемся и поговорим более подробно в отдельном параграфе.
Метод форматирования строк в Python
В процессе написания программ довольно часто возникают ситуации, когда в строку требуется вставить значения, динамически появляющиеся в процессе выполнения программы, например, получаемые в результате пользовательского ввода, чтения данных из файла или вычисления математического выражения. В Python для таких случаев предусмотрен специальный метод str.format(), называемый методом форматирования строк, который принимает произвольное количество позиционных или именованных аргументов и выполняет их подстановку в соответствующих местах (полях) строки str, относительно которой он был вызван (см. пример №20).
# Используем в вызове позиционные аргументы.
str_1 = "а_{}_в_{}_д"
# Выведет а_б_в_г_д.
print(str_1.format('б', 'г'), end='\n\n')
# Используем в фигурных скобках индексы (номера аргументов).
str_2 = "а_{1}_в_{0}_д"
# Выведет а_г_в_б_д.
print(str_2.format('б', 'г'), end='\n\n')
# Используем в вызове именованные аргументы.
str_3 = "а_{let_4}_в_{let_2}_д"
# Опять же выведет а_г_в_б_д.
print(str_3.format(let_2='б', let_4='г'), end='\n\n')
# Используем оба варианта сразу.
str_4 = "а_{0}_в_{let_4}_д"
# Выведет а_б_в_г_д.
print(str_4.format('б', let_4='г'))
а_б_в_г_д
а_г_в_б_д
а_г_в_б_д
а_б_в_г_д
Пример №20. Метод форматирования строк (часть 1).
Как видно из примера, в простейших случаях пустые фигурные скобки или фигурные скобки с индексами замещаются значениями соответствующих позиционных аргументов передаваемых методу. В случае использования в вызове именованных аргументов, вместо фигурных скобок с именами подставляются значения соответствующих именованных аргументов. Однако не стоит забывать, что именованные аргументы должны передаваться после позиционных.
Следует добавить, что метод может принимать значения любого типа данных. Так что можно смело использовать не только строки, но и, например, числа, списки, словари или другие объекты. При этом после индекса или имени в фигурных скобках форматируемой строки допускается использование синтаксиса квадратных скобок для доступа по ключу к элементу словаря или по индексу к элементу последовательности, а также точки для доступа к атрибутам объекта, если, конечно, соответствующий аргумент метода позволяет это сделать (см. пример №21).
# Импортируем модуль math.
import math
# Передаем методу список и словарь.
str_1 = "{} и {}".format(['а', 'б'], {'one': 'в', 'two': 'г'})
# Выведет ['а', 'б'] и {'one': 'в', 'two': 'г'}.
print(str_1, end='\n\n')
# Используем доступ по неотрицат. индексу и ключу (без кавычек).
str_2 = "{0[0]}_{0[1]}_{1[one]}_{1[two]}"
str_2 = str_2.format(['а', 'б'], {'one': 'в', 'two': 'г'})
# Выведет а_б_в_г.
print(str_2, end='\n\n')
# Тоже самое, но для именованных аргументов.
str_3 = "{li[0]}_{li[1]}_{d[one]}_{d[two]}"
str_3 = str_3.format(li = ['а', 'б'], d = {'one': 'в', 'two': 'г'})
# Выведет а_б_в_г.
print(str_3, end='\n\n')
# Используем доступ через имя атрибута.
str_4 = "Число Пи равно {0.pi}".format(math)
# Выведет строку 'Число Пи равно 3.141592653589793'.
print(str_4, end='\n\n')
# Тоже самое, но через именованный аргумент.
str_5 = "Число Пи равно {m.pi}".format(m = math)
# Опять же выведет строку 'Число Пи равно 3.141592653589793'.
print(str_5)
['а', 'б'] и {'one': 'в', 'two': 'г'}
а_б_в_г
а_б_в_г
Число Пи равно 3.141592653589793
Число Пи равно 3.141592653589793
Пример №21. Метод форматирования строк (часть 2).
Обратите внимание, что использование в квадратных скобках отрицательных индексов не допускается, а строковые ключи словарей должны указываться без кавычек (нужно указывать только имя ключа).
Далее, помимо подстановки в строку значений аргументов имеется возможность их предварительного форматирования в соответствии с формальным синтаксисом
выражения
{[field_name][!conversion_flag][:format_spec]}, где
- field_name – необязательный порядковый номер или имя именованного аргумента, за которым может следовать необязательный неотрицательный индекс элемента последовательности в виде [index], необязательное имя ключа словаря в виде [key_name] (кавычки для строковых ключей нужно опускать) или необязательное имя атрибута объекта в виде [.attribute_name] (еще раз посмотрите пример №21).
- conversion_flag – необязательный флаг конвертации, указывающийся после восклицательного знака и позволяющий указать, какую из встроенных функций нужно применить к значению в форматированной строке: s – удобное для человеческого восприятия представление через str() (используется по умолчанию), r – внутреннее представление через repr() или a – форма внутреннего представления через ascii(), когда вместо символов не входящих в набор ASCII выводятся соответствующие экранированные последовательности для символов Юникода (см. пример №22).
- format_spec – необязательная спецификация формата, которая указывается после двоеточия (см. синтаксис ниже).
# Импортируем модуль чисел с фиксированной точностью.
import decimal
# Сохраним число в переменной.
d = decimal.Decimal('3.47')
# Используем флаги по-очереди.
str_1 = "{0} {0!s} {0!r} {0!a}".format(d)
# Выведет 3.47 3.47 Decimal('3.47') Decimal('3.47').
print(str_1, end='\n\n')
# Используем символы не из ASCII.
str_2 = "{0} {0!r} {0!a}".format('2α + 3β')
# Выведет 2α + 3β '2α + 3β' '2\u03b1 + 3\u03b2'.
print(str_2)
3.47 3.47 Decimal('3.47') Decimal('3.47')
2α + 3β '2α + 3β' '2\u03b1 + 3\u03b2'
Пример №22. Метод форматирования строк (часть 3).
Итак, спецификация format_spec указывается после двоеточия и в общем виде имеет вид:
[[fill] align] [sign] [#] [0] [width] [grouping_option] [.precision] [type], где
- fill – символ, выступающий в роли заполнителя, который не может быть символом { или } (по умолчанию используется пробел);
-
align – задает выравнивание вставляемого значения:
- < – выравнивание будет выполняться по левому краю, соответственно символы заполнителя будут размещаться по правому краю (используется по умолчанию для всех объектов, кроме чисел);
- > – выравнивание будет выполняться по правому краю, соответственно символы заполнителя будут размещаться по левому краю (для чисел это значение используется по умолчанию);
- = – применяется только к числовым значениям, добавляя указанное количество символов заполнителя слева от числа, но после знака числа;
- ^ – выравнивание будет выполняться по центру, соответственно символы заполнителя будут размещаться слева и справа от значения (см. пример №23);
# Выравниваем по левому краю с заполнителем *.
str_1 = "({0:*<10}) ({1:*<10})".format('слева', 23.5)
# Выведет (слева*****) (23.5******).
print(str_1, end='\n\n')
# Используем значения по умолчанию.
str_2 = "({0:10}) ({1:10})".format('слева', 23.5)
# Выведет (слева ) ( 23.5).
print(str_2)
(слева*****) (23.5******)
(слева ) ( 23.5)
Пример №23. Метод форматирования строк (часть 4).
-
sign – применяется только для чисел, и может принимать следующие значения:
- знак минуса (-) – отрицательные числа будут отображаться со знаком -, положительные – вообще без знака (используется по умолчанию);
- знак плюса (+) – положительные числа будут отображаться со знаком +, отрицательные – со знаком -;
- символ пробела ( ) – для положительных чисел вместо знака + будет отображаться пробел, а для отрицательных – знак - (см. пример №24);
# Используем умолчания.
str_1 = "({0}, {1})".format(23.5, -3.142)
# Выведет (23.5, -3.142).
print(str_1, end='\n\n')
# Добавляем знак для всех чисел.
str_2 = "({0:+}, {1:+})".format(23.5, -3.142)
# Выведет (+23.5, -3.142).
print(str_2)
(23.5, -3.142)
(+23.5, -3.142)
Пример №24. Метод форматирования строк (часть 5).
-
символ # – используется только для чисел:
- целые числа – задает префикс в нужной системе счисления: #b – число будет выведено в двоичной СС; #o – число будет выведено в восьмеричной СС; #x – число будет выведено в шестнадцатеричной СС;
- вещественные числа – гарантирует наличие десятичной точки (нужно просто указать решетку без всяких дополнительных символов), при этом, если type установлен в g или G, то конечные нули сохраняются;
- комплексные числа – также гарантирует наличие десятичной точки как у действительной, так и у мнимой части числа, при этом, если type установлен в g или G, то конечные нули сохраняются (см. пример №25);
# Используем значение по умолчанию.
# Получим 230.
print("{0:#}".format(230), end='\n\n')
# Отобразим целое число в 2-й и 16-й СС.
# Получим 0b11100110.
print("{0:#b}".format(230))
# Получим 0xe6.
print("{0:#x}".format(230), end='\n\n')
# Гарантируем сохранение десятичной точки.
# Получим 0.3.
print("{0:#}".format(.3))
# Получим (3.+5.j).
print("{0:#}".format(3 + 5j), end='\n\n')
230
0b11100110
0xe6
0.3
(3.+5.j)
Пример №25. Метод форматирования строк (часть 6).
- символ 0 – используется только для чисел, и указывает на необходимость заполнения чисел нулями до ширины, задаваемой параметром width;
- width – задает минимальную ширину поля для подставляемого значения;
-
grouping_option – задает разделитель разрядов тысяч:
- запятая (,) – задает разделение посредством запятой; при этом для получения разделителей, используемых в конкретных локалях, лучше опускать этот параметр, используя для параметра type значение n;
- символ нижнего подчеркивания (_) – задает разделение посредством нижнего подчеркивания в числах с плавающей запятой и целых числах с кодом d; при этом для целых чисел с кодом b, o, x или X разделители будут вставлены через каждые 4 цифры, а для чисел с другими кодами будет вызвано исключение (см. пример №26);
# Задаем ширину в 20 символов с разделителем ,.
str_1 = "({0:20,})".format(23050337.9641)
# Выведет ( 23,050,337.9641).
print(str_1, end='\n\n')
# Заполняем свободное место нулями.
str_2 = "({0:020,})".format(23050337.9641)
# Выведет (000,023,050,337.9641).
print(str_2, end='\n\n')
# Обратите внимание на небольшое отличие.
str_3 = "({0:0>20,})".format(23050337.9641)
# Выведет (0000023,050,337.9641).
print(str_3, end='\n\n')
( 23,050,337.9641)
(000,023,050,337.9641)
(0000023,050,337.9641)
Пример №26. Метод форматирования строк (часть 7).
-
precision – управляет точностью вещественных чисел или задает максимальную ширину поля для строк, точнее:
- для строк – задает максимальную ширину поля для подставляемого значения;
- для целых чисел – не используется вообще;
- для вещественных чисел – если type установлен в g или G, то параметр задает общее количество отображаемых цифр числа; если type установлен в f или F, то параметр задает количество отображаемых цифр числа после десятичной точки (см. пример №27);
# Используем точность по умолчанию.
str_1 = '{0:}'.format(123.456789)
# Выведет 123.456789.
print(str_1, end='\n\n')
# Установим точность в 5 знаков.
str_2 = '{0:.5}'.format(123.456789)
# Выведет 123.46.
print(str_2, end='\n\n')
# Число отформат-ное при помощи флага f.
str_3 = '{0:.5f}'.format(123.456789)
# Выведет 123.45679.
print(str_3, end='\n\n')
# Повысим точность с флагом f.
str_4 = '{0:.7f}'.format(123.456789)
# Выведет 123.4567890.
print(str_4, end='\n\n')
# Задаем максимальную ширину.
str_5 = '{0:.5}'.format('Строка.')
# Выведет Строк.
print(str_5, end='\n\n')
# Увеличим максимальную ширину.
str_6 = '{0:.10}'.format('Строка.')
# Выведет всю строку.
print(str_6)
123.456789
123.46
123.45679
123.4567890
Строк
Строка.
Пример №27. Метод форматирования строк (часть 8).
-
type – задает тип подставляемых данных и способ их отображения при помощи следующих кодовых символов:
- s – строковый формат (используется по умолчанию);
- d – используется по умолчанию для целых чисел и перед выводом преобразует их в десятичную систему счисления;
- b – преобразует целые числа в двоичную систему счисления;
- c – преобразует целые числа в соответствующие символы Юникода в 16-ом представлении: число сначала переводится в 16-ю систему счисления, после чего формируется соответствующая экранированная последовательность Юникода вида \uhhhh, которая и представляет целевой символ;
- o – преобразует целые числа в восьмеричную систему счисления;
- x – преобразует целые числа в шестнадцатеричную систему счисления, используя строчные буквы из последовательности abcdef для обозначения цифр превыщающих 9;
- X – преобразует целые числа в шестнадцатеричную систему счисления, используя заглавные буквы из последовательности ABCDEF для обозначения цифр превыщающих 9;
- e – преобразует вещественные числа в экспоненциальную форму, в которой показатель степени обозначается строчной буквой e, а точность равна 6 знакам после запятой; спецификатор работает и с целыми числами, предварительно преобразуя их в вещественный тип;
- E – перед выводом преобразует вещественные числа в экспоненциальную форму, в которой показатель степени обозначается заглавной буквой E, а точность равна 6 знакам после запятой; спецификатор работает и с целыми числами, предварительно преобразуя их в вещественный тип;
- f – перед выводом преобразует вещественные числа в стандартную форму с точностью до 6 знаков после запятой;
- F – аналогичен f, однако для обозначения inf и nan используется верхний регистр символов;
- g – для вывода используется общий формат, т.е. для небольших чисел параметр действует как f, а для очень больших – как символ e;
- G – для вывода используется общий формат, т.е. для небольших чисел параметр действует как F, а для очень больших – как символ E;
- n – для целых чисел параметр аналогичен значению d, а для вещественных – аналогичен значению g; в обоих случаях параметр учитывает региональные настройки, используя характерный для текущего региона символ-разделитель целой и дробной части числа и разделитель разрядов; по умолчанию в качестве разделителя целой и дробной части числа используется точка, а в качестве разделителя разрядов – пустая строка;
- % – число умножается на 100 с последующим переключением на код f и отображением знака процента в конце (см. пример №28).
# Строки.
# Используем тип по умолчанию, т.е. s.
print('{0:}'.format('123'), end='\n\n')
# Ошибка типа аргумента (должен быть str).
# print('{0:s}'.format(123))
# Целые числа.
# Выведет 123
print('{0:}'.format(123))
# Выведет 1111011.
print('{0:b}'.format(123))
# Выведет символ { (соотв. 16-му коду \u007b).
print('{0:c}'.format(123))
# Выведет 123.
print('{0:d}'.format(123))
# Выведет 173.
print('{0:o}'.format(123))
# Выведет 7b.
print('{0:x}'.format(123))
# Выведет 7B.
print('{0:X}'.format(123))
# Выведет 123.
print('{0:n}'.format(123), end='\n\n')
# Вещественные числа.
# Выведет 1.234500e+02.
print('{0:e}'.format(123.345))
# Выведет 1.233450E+02.
print('{0:E}'.format(123.345))
# Выведет 123.345000.
print('{0:f}'.format(123.345))
# Выведет 815108633516821708800.000000.
print('{0:F}'.format(123.345**10))
# Выведет nan, inf.
print('{0:f}, {1:f}'.format(float('nan'), float('inf')))
# Выведет NAN, INF.
print('{0:F}, {1:F}'.format(float('nan'), float('inf')))
# Выведет 123.345.
print('{0:g}'.format(123.345))
# Выведет 8.15109E+20.
print('{0:G}'.format(123.345**10))
# Выведет 12334.500000%.
print('{0:%}'.format(123.345))
# Выведет 123.345.
print('{0:n}'.format(123.345), end='\n\n')
123
123
1111011
{
123
173
7b
7B
123
1.233450e+02
1.233450E+02
123.345000
815108633516821708800.000000
nan, inf
NAN, INF
123.345
8.15109E+20
12334.500000%
123.345
Пример №28. Метод форматирования строк (часть 9).
В конце хотелось бы отметить еще одну тонкую деталь. Для достижения эффекта динамического изменения параметров форматирования допускается использование в форматируемой строке полей внутри других полей, т.е. можно использовать фигурные скобки внутри других фигурных скобок. При этом разрешается только один уровень вложенности, позволяющий подставлять параметры форматирования налету в процессе выполнения программы (см. пример №29).
# Отобразим число в экспоненциальной форме.
str_1 = 'Число {0} в эксп. форме: {0:{1}}'.format(23.75, 'e')
# Выведет 2.375000e+01.
print(str_1)
# Отобразим число в обычной форме.
str_2 = 'Число {0} в станд. форме: {0:{1}}'.format(23.75, 'n')
# Выведет 23.75.
print(str_2)
Число 23.75 в эксп. форме: 2.375000e+01
Число 23.75 в станд. форме: 23.75
Пример №29. Метод форматирования строк (часть 10).
Как видим, метод форматирования строк в Python обладает огромным потенциалом возможностей, и местами даже похож на мини-язык высокого уровня, позволяющий довольно точно описывать параметры форматирования строк.
Использование F-строк в Python
F-строки (от англ. formatted string literals) представляют собой еще один весьма удобный инструмент для интерполяции и форматирования строк, позволяющий использовать и вычислять внутри них значения выражений. F-строки в Python легко читаемы, кратки, более быстрые и менее подвержены ошибкам по сравнению с традиционными инструментами вроде метода str.format() или оператора %.
Для создания F-строки необходимо добавить перед открывающей кавычкой букву f (или F), а для вставки значений или выражений в строку – фигурные скобки (см. пример №30).
# Создаем объекты.
li = [35.6, 1.7]
s = 'Ok'
# Вставляем эл-ты в строку и вычисляем.
# Выведет 35.6*1.7 = 60.52.
print(f"{li[0]}*{li[1]} = {li[0]*li[1]}")
# Использование 2-х и 3-х скобок.
# Выведет {li[0]*li[1]}.
print(f'{{li[0]*li[1]}}')
# А так {60.52}.
print(f'{{{li[0]*li[1]}}}')
# Одни f-строки внутри других.
# Выведет 35.6, 1.7, Ok.
print(f'{li[0]}, {F"{li[1]}"}, {f"{s}"}')
# Выражение if/else внутри f-строки.
# Выведет Ok.
print(f'{s if li[0] > li[1] else -1}')
# Использование спецификатора =.
# Выведет li = [35.6, 1.7].
print(f'{li = }')
# Многострочные f-строки.
li_elems = f'''li[0]: {li[0]}
li[1]: {li[1]}'''
print(li_elems)
35.6*1.7 = 60.52
{li[0]*li[1]}
{60.52}
35.6, 1.7, Ok
Ok
li = [35.6, 1.7]
li[0]: 35.6
li[1]: 1.7
Пример №30. Использование F-строк (часть 1).
Как видим, использовать F-строки действительно просто и удобно. Все что нужно, это подставлять в фигурные скобки нужный объект, выражение или даже другую F-строку. Более того, F-строки поддерживают и описанную выше спецификацию мини-языка для форматирования строк, не уступая в этом методу str.format() (см. пример №31)
# Импортируем модуль чисел с фиксированной точностью.
import decimal
# Сохраним число в переменной.
d = decimal.Decimal('3.47')
# Использование флагов отображения.
str_1 = "{0} {0!s} {0!r} {0!a}".format(d)
str_2 = f"{d} {d!s} {d!r} {d!a}"
# Выведет 3.47 3.47 Decimal('3.47') Decimal('3.47').
print(str_1)
print(str_2, end='\n\n')
# Спецификатор : и флаг f.
str_3 = '{0:.5f}'.format(123.456789)
str_4 = f'{123.456789:.5f}'
# Выведет 123.45679.
print(str_3)
print(str_4)
3.47 3.47 Decimal('3.47') Decimal('3.47')
3.47 3.47 Decimal('3.47') Decimal('3.47')
123.45679
123.45679
Пример №31. Использование F-строк (часть 2).
При работе с F-строками следует помнить о некоторых важных моментах и ограничениях (см. пример №32):
- пустые выражения, т.е. пустые скобки {}, внутри таких строк недопустимы;
- их нельзя использовать в качестве строк документации;
- как лямбда-выражения, так и выражения присваивания := должны быть заключены в явные круглые скобки;
- поскольку потенциал F-строк стремительно изменялся от версии к версии, многие последние возможности (например, использование комментариев) недоступны для предыдущих версий Питона.
# Выведет x^2 = 4.
print(f"x^2 = {(lambda x: x**2)(2)}")
# at 0x000001F...
print(f"{(lambda x: x**2)}")
# А вот здесь получим ошибки.
# print(f"{lambda x: x**2}")
# print(f"Пустое выражение запрещено! {}")
# f-строки не подходят для документирования.
def my_func(): f"""Документация функции"""
# Выведет None.
print(my_func.__doc__)
# Комментарии допустимы лишь с версии 3.12.
# print(f'{5 # Число.}')
x^2 = 4
at 0x000001C5DF6204A0>
None
Пример №32. Использование F-строк (часть 3).
Краткие итоги параграфа
- Строки используются в Python для хранения и представления текстовой информации и представляют собой неизменяемые упорядоченные последовательности символов Юникода. По умолчанию в скриптах используется кодировка UTF-8.
- Чтобы создать литерал строки, достаточно заключить требуемую последовательность символов в одинарные (например, 'строка'), двойные (например, "строка") или тройные кавычки (например, '''строка''' или """строка"""). При этом допускается использование кавычек одного типа внутри строковых литералов, заключенных в кавычки другого типа (например, '_ "F" _'), либо внутри строковых литералов, заключенных в кавычки того же типа, предварительно экранировав их при помощи обратного слеша \ (например, '_ \'F\' _').
- Если строковый литерал получается довольно длинным, возникает необходимость в его переносе на другую строку программного кода. Сделать это можно несколькими способами: использовать обратный слеш (\) в требуемом месте переноса строки; использовать строки в тройных кавычках, которые как раз и предназначены для оформления больших блоков текста внутри исходного кода; разбить строку на несколько частей и затем объединить их при помощи символа плюса (+), при этом не забыв использовать круглые скобки.
- Если символ отсутствует на клавиатуре, отобразить его внутри строкового литерала исходного кода программы можно при помощи соответсвующей экранированной (управляющей) последовательности. Например, для отображения символа греческого алфавита Ω можно использовать управляющую последовательность \u03A9.
- Несмотря на то, что строки в Python представляют собой неизменяемые упорядоченные последовательности символов Юникода, доступ к ее отдельным символам можно получить при помощи операции индексирования. Для этого нужно указать в квадратных скобках после имени или литерала строки порядковый номер символа в последовательности, не забывая, что нумерация символов в строке начинается с нуля. Более того, доступ к символам строки возможен также и по отрицательным индексам. В этом случае можно считать, что отсчет ведется с конца строки и начинается с -1. Например, операция '12345'[3] вернет нам символ '4', а '12345'[-3] вернет нам символ '3'.
- Также для строк (как и других упорядоченных последовательностей) доступна операция извлечения среза, которая без особых усилий позволяет извлекать не только отдельные символы, но и целые диапазоны символов, не прибегая при этом к специальным методам или встроенным функциям. Например, операция среза '0123456789'[1:7:2] вернет нам новую строку '135', в которой будет присутствовать каждый второй символ из диапазона индексов от 1 до 7, но не включая сам конечный предел 7.
- Что касается знакомых нам арифметических операторов, то + используется для объединения строк в одну (например, операция конкатенации 'по' + 'езд' вернет строку 'поезд'), а комбинированный оператор += добавляет целевую строку в конец текущей (например, инструкции s = 'по' и s += 'езд' сохранят в переменной строку 'поезд'). Оператор умножения * и соответсвующий ему комбинированный оператор *= служат для получения копии строки, состоящей из повторений исходной строки указанное число раз (например, операция '-'*5 вернет строку '-----').
- Также к строкам применимы оператор отрицания not и оператор проверки на вхождение in, который в данном случае совершает поиск требуемой подстроки (левый операнд) в целевой строке (правый операнд). В случае успеха операция с участием in возвращает True, иначе – False. Например, 'gi' in 'georgian' вернет нам True. В тоже время, если использовать оператор in в паре с оператором отрицания not, то на выходе операции 'gi' not in 'georgian' мы получим False.
- Строки обладают внушительным набором методов, которые позволяют выполнять широкий спектр операций над ними. Для их использования не нужно импортировать никаких модулей, т.к. они уже встроены в сам интерпретатор. Для вызова метода нужно просто использовать синтаксис точки для доступа к атрибутам объекта. Например, чтобы получить копию строки, в которой все символы будут в верхнем регистре, можно использовать инструкцию s = 'abcdef'.upper(). Методов очень много, поэтому необязательно запоминать их все. Наиболее простые и часто использующиеся запомнятся автоматически, а остальные всегда можно найти в стандартной библиотеке в разделе «Built-in types» ⇨ «Text Sequence Type – str».
- Отдельно стоит выделить метод форматирования строк, который позволяет подставлять значения различных типов непосредственно в указанные места (поля) строки, обозначаемые фигурными скобками. Опять же, на выходе мы получаем измененную копию строки, а не саму строку. Метод обладает довольно внушительным набором функциональных возможностей для довольно точного форматирования строк.
- Однако наиболее привлекательным инструментом для интерполяции и форматирования строк, все таки следует считать F-строки, которые позволяют использовать и вычислять внутри себя значения выражений. В сравнении с методом str.format() они более быстрые и менее подвержены ошибкам. Для создания F-строки необходимо добавить перед открывающей кавычкой букву f (или F), а для вставки значений или выражений в строку – фигурные скобки {}.
Вопросы и задания для самоконтроля
1. Как мы узнали, в Python строки представляют из себя упорядоченные последовательности символов Юникода. Можно ли поменять местами два соседних символа строки, удалить символ из строки? Почему? Показать решение.
Ответ. В Python строки действительно представляют из себя упорядоченные последовательности символов Юникода. Но эти последовательности неизменяемые! Поэтому мы не можем изменять строку непосредственно, удаляя или добавляя в нее символы, а также меняя их местами. Для достижения похожего эффекта можно создать измененную копию строки и присвоить ее текущей переменной, заменив тем самым оригинальную строку.
2. Какие из представленых литералов относятся к типу str: ['зимний', 'летний'], '3.4', 5.0, "Питон"? Проверьте типы программно. Показать решение.
Ответ. Тип str: '3.4' и "Питон".
# Выводим типы представленных литералов.
print("Тип ['зимний', 'летний']:", type(['зимний', 'летний']))
print("Тип '3.4':", type('3.4'))
print("Тип 5.0:", type(5.0))
print('Тип "Питон":', type("Питон"))
Тип ['зимний', 'летний']: <class 'list'>
Тип '3.4': <class 'str'>
Тип 5.0: <class 'float'>
Тип "Питон": <class 'str'>
3. Какая кодировка используется в python-скриптах по умолчанию? Показать решение.
Ответ. По умолчанию в скриптах используется кодировка UTF-8.
4. Как записать строку в одинарных/двойных кавычках внутри другой строки в одинарных/двойных кавычках? Показать решение.
Ответ. Необходимо экранировать одинарные/двойные кавычки внутренней подстроки символом обратного слеша.
# Экрарнируем символы кавычек.
print('5 – это \'пять\'.')
print("7 – это \"семь\".")
5 – это 'пять'.
7 – это "семь".
5. Исправьте ошибки в исходном коде ниже. Показать решение.
# Разрешаются одиночные и двойные кавычки.
str_1 = "Отель "Орбита" в Минске"
# Разрешаются только двойные кавычки.
str_2 = "Отель "Орбита" в Минске"
# Разрешаются одиночные и двойные кавычки.
str_1 = "Отель "Орбита" в Минске"
# Разрешаются только двойные кавычки.
str_2 = "Отель "Орбита" в Минске"
# Разрешаются одиночные и двойные кавычки.
str_1 = 'Отель "Орбита" в Минске'
# Разрешаются только двойные кавычки.
str_2 = "Отель \"Орбита\" в Минске"
6. Дайте определение экранированной последовательности. Как с ее помощью записать символ перевода строки? Показать решение.
Ответ. Экранированная последовательность – это специальная последовательность символов, начинающаяся со знака обратного слеша, которая обозначает символ, не всегда представимый внутри строки другими способами. Например, для представления символа перевода строки используется комбинация символов \n, а для экранирования самого обратного слеша – комбинация \\ из двух обратных слешей.
# Используем символ перевода строки.
print('1-я строка.\n2-я строка.')
1-я строка. 2-я строка.
7. Как отключить механизм экранирования для строки? Показать решение.
Ответ. Нужно использовать перед строкой символ r.
# Используем символ перевода строки.
print('1-я строка.\n2-я строка.')
# Отключаем экранирование символов.
print(r'1-я строка.\n2-я строка.')
1-я строка. 2-я строка. 1-я строка.\n2-я строка.
8. Какой символ будет присвоен переменным в инструкциях simb_1 = '1234567'[3] и simb_2 = '1234567'[-3]? Проверьте свой ответ программно. Показать решение.
# Находим символы по индексам.
simb_1 = '1234567'[3]
simb_2 = '1234567'[-3]
# Выведет 4.
print('simb_1:', simb_1)
# Выведет 5.
print('simb_2:', simb_2)
simb_1: 4 simb_2: 5
9. Какие подстроки будут присвоены переменным в инструкциях s_1 = '1234567'[1:4], s_2 = '1234567'[-5:-3] и s_3 = '1234567'[::2]? Проверьте свой ответ программно. Показать решение.
# Находим срезы.
s_1 = '1234567'[1:4]
s_2 = '1234567'[-5:-3]
s_3 = '1234567'[::2]
# Выведет 234.
print('s_1:', s_1)
# Выведет 34.
print('s_2:', s_2)
# Выведет 1357.
print('s_3:', s_3)
s_1: 234 s_2: 34 s_3: 1357
10. Как при помощи срезов получить строку-«перевертыш», т.е. строку, в которой символы будут идти в обратном порядке? Например, для строки 'бобер' «перевертышем» будет строка 'ребоб'. Показать решение.
# Сохраняем строку в переменной.
s = 'бобер'
# Получаем строку-перевертыш.
s = s[::-1]
# Выводим ее на экран.
print(s)
ребоб
11. Назовите методы строк, которые позволяют подсчитать количество вхождений подстрок в строке, привести все символы в нижний регистр, заменить одни подстроки на другие, разбить строку на список подстрок по указанному разделителю, проверить строку на возможность использования в качестве имени переменной. Показать решение.
Ответ. str.count(sub[, start[, end]]) – подсчет количества вхождений подстрок в строке, str.lower() – приведение всех символов в нижний регистр, str.replace(old, new[, count]) – замена одних подстрок на другие, str.split(sep=None, maxsplit=-1) – разбиение строки на список подстрок по указанному разделителю, str.isidentifier() – проверка строки на возможность использования в качестве имени переменной,.
12. В чем заключается разница между методами str.index(sub[, start[, end]]) и str.find(sub[, start[, end]])? Показать решение.
Ответ. Оба метода возвращают индекс первого вхождения подстроки sub в строку str или в срез строки str[start:end], если он задан. Но в случае неудачного поиска str.index(sub[, start[, end]]) возвращает исключение ValueError, а метод str.find(sub[, start[, end]]) возвращает -1.
13. Какими преимуществами в сравнении с методом форматирования строк str.format() обладают F-строки? Показать решение.
Ответ. F-строки в Python легко читаемы, кратки, более быстрые и менее подвержены ошибкам по сравнению с традиционными инструментами вроде метода str.format().
14. Дополнительные тесты по теме расположены в разделе «Текстовые строки» нашего сборника тестов.
15. Дополнительные упражнения и задачи по теме расположены в разделе «Текстовые строки» нашего сборника задач и упражнений.
Быстрый переход к другим страницам
- Числа в Python
- Строки в Python
- Списки в Python
- К содержанию учебника