Строки
Содержание
Строки
Строки предоставляют возможность хранить и оперировать с данными, представленными в виде последовательности символов. Язык Python из "коробки" имеет широкую поддержку строк и позволяет обращаться с символами из самых разных алфавитов.
Тип str
Для взаимодействия со строками в языке есть встроенный тип str
.
Его литералом являются одиночные '
или двойные кавычки "
.
Символы (код), заключенный между кавычками будет восприниматься Python, как строка:
>>> s1 = 'Привет! Я строка!'
>>> s2 = "Привет! Я тоже строка!"
>>> type(s1)
<class 'str'>
>>> type(s2)
<class 'str'>
Строка может быть пустой: ''
или ""
.
Чтобы воспользоваться кавычками внутри строки, есть два пути:
- Воспользоваться в качестве литерала одним видом кавычек, а внутри строки пользоваться вторым видом кавычек;
- Экранировать кавычки внутри строки с помощью символа экранирования (escape character) \, он же называется обратной косой чертой.
Например:
>>> s4 = '\'Я внутри одинарных кавычек\', а "я внутри двойных"'
>>> s4
'\'Я внутри одинарных кавычек\', а "я внутри двойных"'
>>> print(s4)
'Я внутри одинарных кавычек', а "я внутри двойных"
Здесь в качестве литерала взяты одинарные кавычки, для первой части фразы используется экранирование, а для второй двойные.
Более того, для удобного написания многострочной строки (простите), можно воспользоваться тройными одинарными или тройными двойными кавычками, причём внутри такой строки экранирование не понадобится:
>>> multiline_str = '''Я первая строка
... I'm the second line
... А я третья!'''
>>> multiline_str
"Я первая строка\nI'm the second line\nА я третья!"
>>> print(multiline_str)
Я первая строка
I'm the second line
А я третья!
Заметьте, что во второй строке экранирование кавычки не понадобилось (I'm
).
Также, вы могли заметить, что при вызове в интерактивном режиме строка отображается в виде, в котором представлена в программе, и только при печати print()
отображается ожидаемо.
В случае печати чисел это было не заметно.
Напоследок, небольшой список часто используемых экранированных последовательностей (escape sequence):
- символ новой строки
\n
- табуляция
\t
, с помощью табуляции можно получать удобные для чтения таблицы - кавычки
\'
,\"
- обратная косая
\\
Доступ к символам и срезы строк
Так же, как и список, строка это упорядоченная последовательность. Если список это последовательность объектов произвольного типа, то строка это последовательность символов.
Можно узнать длину строки, получить символ на определённой позиции и даже получить срез строки:
>>> s = "Hello, World!"
>>> len(s)
13
>>> s[0]
'H'
>>> s[7:]
'World!'
>>> s[::2]
'Hlo ol!'
Конкатенация и неизменяемость строк
Простейшая операция над двумя строками это конкатенация - приписывание второй строки в конец первой:
>>> str_1 = "ABC"
>>> str_2 = "def"
>>> str_1 + str_2
'ABCdef'
>>> str_2 + str_1
'defABC'
Более того, с помощью символа умножения *
можно конкатенировать строку с самой собой несколько раз:
>>> str_1
'ABC'
>>> str_1 * 10
'ABCABCABCABCABCABCABCABCABCABC'
>>> 5 * str_1
'ABCABCABCABCABC'
>>> str_1
'ABC'
>>> str_2
'def'
>>> (str_1 + str_2) * 5
'ABCdefABCdefABCdefABCdefABCdef'
Строки являются неизменяемым типом в Python. При попытке изменения символа на какой-то позиции произойдёт ошибка:
>>> s = 'ваза'
>>> s[0] = 'б'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
На самом деле, в примерах по конкатенации Python создавал новые объекты строк. Даже операция инкрементирования создаёт новую строку, в чём можно убедиться, узнав их идентификатор (в данном случае это равносильно адресу в памяти):
>>> s = 'a'
>>> id(s)
4465232176
>>> s += 'b'
>>> s
'ab'
>>> id(s)
4466564720
Некоторые методы строк
У строк в Python огромное количество методов. Не верите? Вот они:
str.capitalize()
str.casefold()
str.center(width[, fillchar])
str.count(sub[, start[, end]])
str.encode(encoding="utf-8", errors="strict")
str.endswith(suffix[, start[, end]])
str.expandtabs(tabsize=8)
str.find(sub[, start[, end]])
str.format(*args, **kwargs)
str.format_map(mapping)
str.index(sub[, start[, end]])
str.isalnum()
str.isalpha()
str.isascii()
str.isdecimal()
str.isdigit()
str.isidentifier()
str.islower()
str.isnumeric()
str.isprintable()
str.isspace()
str.istitle()
str.isupper()
str.join(iterable)
str.ljust(width[, fillchar])
str.lower()
str.lstrip([chars])
static str.maketrans(x[, y[, z]])
str.partition(sep)
str.replace(old, new[, count])
str.rfind(sub[, start[, end]])
str.rindex(sub[, start[, end]])
str.rjust(width[, fillchar])
str.rpartition(sep)
str.rsplit(sep=None, maxsplit=-1)
str.rstrip([chars])
str.split(sep=None, maxsplit=-1)
str.splitlines([keepends])
str.startswith(prefix[, start[, end]])
str.strip([chars])
str.swapcase()
str.title()
str.translate(table)
str.upper()
str.zfill(width)
Мы разберём только некоторые из них (для остальных есть help(str.method_name)
:-)
Поиск
Метод str.find
ищет подстроку в строке и возвращает индекс начала найденной подстроки.
Если вхождение не найдено, вернётся -1:
>>> s = 'Hello, World!'
>>> s.find('World')
7
>>> s[7]
'W'
>>> s.find('Universe')
-1
Этот метод имеет два необязательных аргумента start
и end
.
Если их указать, то поиск будет осуществляться в срезе строки s[start:end]
:
>>> s
'Hello, World!'
>>> s.find('o')
4
>>> s[3:6]
'lo,'
>>> s.find('o', 7)
8
>>> s[7:10]
'Wor'
И, как видно, str.find
осуществляет поиск первого вхождения подстроки, начиная слева.
Чтобы осуществить поиск подстроки, начиная справа (т.е. с конца) строки, можно воспользоваться методом str.rfind
.
Сравните:
>>> s
'Hello, World!'
>>> s.rfind('o')
8
>>> s.find('o')
4
Метод str.rfind
имеет тот же интерфейс, что и str.find
: он имеет два необязательных аргумента, чтобы задать диапазон поиска и возвращает -1, если подстрока не найдена.
Подсчёт
Методом str.count
можно подсчитать количество вхождений подстроки в строку:
>>> s = 'Пингвины не любят окна.'
>>> s.count('а')
1
>>> s.count('ин')
2
>>> s.count('яблоки')
0
Диапазон поиска можно указать так же, как в str.find
.
Замена
Для замены подстроки в строке существует метод str.replace
:
>>> src = 'Пингвины не любят окна.'
>>> replaced = src.replace('Пингвины', 'Даже окна')
>>> src
'Пингвины не любят окна.'
>>> replaced
'Даже окна не любят окна.'
Так как строки в Python неизменяемые, то str.replace
на базе исходной строки создает и возвращает новую.
У этого метода есть дополнительный параметр - количество производимых замен. Если этот параметр выставлен в -1 (значение по умолчанию), то произойдёт замена всех вхождений.
>>> s = 'aaaaa'
>>> s.replace('a', 'b')
'bbbbb'
>>> s.replace('a', 'b', 3)
'bbbaa'
Разбиение и объединение
По существу, вы уже знакомы с этими операциями и применяли их.
Можно разбивать строку на основе подстроки с помощью str.split
.
Результатом этой операции является список.
Например, может стоять задача по разбиению предложения на слова:
>>> sentence = 'Пингвины не любят окна.'
>>> sentence.split()
['Пингвины', 'не', 'любят', 'окна.']
>>> sentence2 = 'вставка, выбор, пузырёк, подсчёт, Хоар, слияние'
>>> sentence2.split(', ')
['вставка', 'выбор', 'пузырёк', 'подсчёт', 'Хоар', 'слияние']
В первом случае в качестве подстроки для разбиения используется значение по умолчанию: разбиение по символам, обозначающих пустое пространство (пробелы, табуляция, перенос строки).
Во втором случае разбиение задано явно - по подстроке ', '
.
Больше примеров:
>>> sentence3 = 'вставка -- выбор -- пузырёк -- подсчёт -- Хоар -- слияние'
>>> sentence3.split()
['вставка', '--', 'выбор', '--', 'пузырёк', '--', 'подсчёт', '--', 'Хоар', '--', 'слияние']
>>> sentence3.split('--')
['вставка ', ' выбор ', ' пузырёк ', ' подсчёт ', ' Хоар ', ' слияние']
>>> sentence3.split(' -- ')
['вставка', 'выбор', 'пузырёк', 'подсчёт', 'Хоар', 'слияние']
У str.split
есть ещё один необязательный аргумент - количество разбиений.
Итак, str.split
разбивает строку по подстроке и возвращает список строк.
Обратная операция это объединение массива строк в одну строку, она осуществляется с помощью str.join
:
>>> sentence3 = 'вставка -- выбор -- пузырёк -- подсчёт -- Хоар -- слияние'
>>> sort_algs = sentence3.split(' -- ')
>>> sort_algs
['вставка', 'выбор', 'пузырёк', 'подсчёт', 'Хоар', 'слияние']
>>> ''.join(sort_algs)
'вставкавыборпузырёкподсчётХоарслияние'
>>> ' '.join(sort_algs)
'вставка выбор пузырёк подсчёт Хоар слияние'
>>> ' + '.join(sort_algs)
'вставка + выбор + пузырёк + подсчёт + Хоар + слияние'
Этот метод более гибкий для входных данных и позволяет объединять не только список строк, но и любой другой итерируемый объект. Главное, чтобы этот объект содержал только строки:
>>> ' '.join(range(10))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected str instance, int found
>>> ' '.join(map(str, range(10)))
'0 1 2 3 4 5 6 7 8 9'
Префикс-функция, алгоритм Кнута-Морриса-Пратта, Z-функция
Описание алгоритмов вы можете найти по ссылке.
Контест №12
Участвовать в контесте. (Альтернативная ссылка)