7.Работа со строками

Базовые приёмы

Для создания строк, мы используем парные кавычки '' или "": s1 = 'Python'
s2 = "Pascal"
Для создания пустой строки, мы пишем s = '' или s = "".

Для считывания текстовых данных в строковую переменную, мы используем функцию input(): s = input()

Операторы + и * можно использовать для строк. Оператор + сцепляет две и более строк. Это называется конкатенацией строк (нельзя пытаться сложить строку и число). Оператор * повторяет строку указанное количество раз: print('AB' + 'cd') # 'ABcd'
print('A' + "7" + 'B') # 'A7B'
print('Hey' * 3) # 'HeyHeyHey'

Мы можем узнать длину строки с помощью функции len: length = len("Hello")
print(length) # 5

С помощью оператора in, мы можем проверять, находится ли одна строка в составе другой. То есть, является ли одна строка подстрокой другой: s = 'Hello my friend'
if 'friend' in s:
print("You're my friend :)")
else:
print("You're not my friend :(")

Если возникает необходимость внутри строки использовать какие-либо кавычки, то можно поступить так, как в примере выше: "You're ...", использовать один вид кавычек внутри другого вида, но если необходимо использовать разные виды кавычек, то можно использовать экранирование с помощью символа \ обратный слэш: 'You\'re ...'. Если мы выведем эту строку и предыдущую, то получим один результат.

Существуют разные экранированные последовательности, рассмотрим несколько из них:

  • \\ - Символ обратного слеша (остается один символ \)
  • \' - Апостроф (остается один символ ')
  • \" - Кавычка (остается один символ ")
  • \n - Новая строка (перевод строки)
  • \t - Табуляция

Индексация строк

Очень часто бывает необходимо обратиться к конкретному символу в строке. Для этого в Python используются квадратные скобки [], в которых указывается индекс (номер) нужного символа в строке: s = 'Python'
print(s[0]) # 'P'
print(s[1]) # 'y'
print(s[5]) # 'n'
Обратите внимание первый символ строки равен s[0], а не s[1]. В Python индексация начинается с 0, по аналогии с функцией range(n), которая генерировала последовательность натуральных чисел от 0 до n - 1.

В отличие от многих языков программирования, в Python есть возможность работы с отрицательными индексами. Если первый символ строки имеет индекс 0, то последнему элементу присваивается индекс -1. s = 'Python'
print(s[-1]) # 'n'
print(s[5]) # 'n'
print(s[-3]) # 'h'

Частая ошибка у начинающих программистов — обращение по несуществующему индексу в строке. Например, если s = 'Python', и мы попытаемся обратится к s[17], то мы получим ошибку:
IndexError: string index out of range

Ошибка возникает, поскольку строка содержит всего 6 символов.

Обратите внимание: если длина строки s равна len(s), то при положительной нумерации слева направо, последний элемент имеет индекс равный len(s) - 1, а при отрицательной индексации справа налево, первый элемент имеет индекс равный -len(s).

Итерирование строк

Очень часто нужно просканировать всю строку целиком, обрабатывая каждый ее символ. Для этого удобно использовать цикл for. Напишем программу, которая выводит каждый символ строки на отдельной строке: s = 'abcdef'
for i in range(len(s)):
print(s[i])
Мы передаем в функцию range() длину строки len(s). В нашем случае длина строки s, равна 6. Таким образом, вызов функции range(len(s)) имеет вид range(6) и переменная цикла i последовательно перебирает все значения от 0 до 5. Это означает, что выражение s[i] последовательно вернет все символы строки s. Такой способ итерации строки удобен, когда нам нужен не только сам элемент s[i], но и его
индекс i.

Если нам не нужен индекс самого символа, то мы можем использовать более короткий способ итерации: s = 'abcdef'
for c in s:
print(c)
Этот цикл пройдет по строке s, придавая переменной цикла c значение каждого символа (!) в отличие от предыдущего цикла, в котором переменная цикла «бегала» по индексам строки.

Срезы строк

Иногда нужно бывает работать с целыми частями строки, в таком случае мы используем срезы. С помощью среза мы можем получить несколько символов исходной строки, создав диапазон индексов, разделенных двоеточием: s = 'abcdefghij'

print(s[2:5]) # 'cde'
print(s[0:6]) # 'abcdef'
print(s[2:7]) # 'cdefg'

При построении среза первое число – это то место, где начинается срез (включительно), а второе – это место, где заканчивается срез (невключительно). Разрезая строки, мы создаем подстроку, которая по сути является строкой внутри другой строки.

Если опустить второй параметр в срезе s[x:] (но поставить двоеточие), то срез берется до конца строки. Аналогично если опустить первый параметр s[:y], то можно взять срез от начала строки. Срез s[:] совпадает с самой строкой s. s = 'abcdefghij'

print(s[5:]) # 'fghij'
print(s[:6]) # 'abcdef'
print(s[:]) # 'abcdefghij'

Мы также можем использовать отрицательные индексы для создания срезов. Как уже говорилось ранее, отрицательные индексы строки начинаются с -1 и отсчитываются до достижения начала строки. При использовании отрицательных индексов первый параметр среза должен быть меньше второго, либо должен быть пропущен. s = 'abcdefghij'

print(s[-9:-4]) # 'bcdef'
print(s[-3:]) # 'hij'
print(s[:-3]) # 'abcdefg'

Мы можем передать в срез третий необязательный параметр, который отвечает за шаг среза. К примеру, срез s[1:7:2] создаст строку bdf, состоящую из каждого второго символа (индексы 1,3,5 правая граница не включена в срез).

Если в качестве шага среза указать отрицательное число, то символы будут идти в обратном порядке: s = 'abcdefghij'
print(s[::-1]) # 'jihgfedcba'

Изменение символа строки по индексу

Предположим, у нас есть строка s = 'abcdefghij' и мы хотим заменить символ с индексом 4 на 'X'. Можно попытаться написать код: s[4] = 'X' Однако такой код не работает. В Python строки являются неизменяемыми, то есть мы не можем менять их содержимое с помощью индексов.

Если мы хотим поменять какой-либо символ строки s, мы должны создать новую строку. Следующий код использует срезы и решает поставленную задачу: s = s[:4] + 'X' + s[5:] Мы создаем два среза: от начала строки до 5-го символа (не включительно) и с 6-го символа (включительно) по конец строки, а между ними вставляем нужный нам символ, который встанет на 5-ю позицию (4 индекс).

Сравнение строк

Сравнение строк Мы можем сравнивать строки с помощью знаков сравнения (>, <, ==, >=, <=, !=). Ниже вы увидите простейший пример сравнения строк в Python с помощью соответствующих операторов: > и <. Давайте сравним строки со словами banana и apple: print("apple" > "banana") # False
print("apple" < "banana") # True

Так как буква «a» находится перед «b», слово apple будет находиться перед словом banana, что логично (то есть banana больше, чем apple). Однако всё сложнее, чем может показаться на первый взгляд. Давайте для наглядности сравним, равны ли слова Apple и apple: print("apple" == "Apple") # False
print("apple" > "Apple") # True

Мы увидим отсутствие равенства, а всё потому, что в Python одинаковые буквы, имеющие разный регистр, считаются разными символами, и компьютер их различает по присвоенным им уникальным значениям.

Что касается нашей ситуации, то здесь латинская «А» имеет значение 65, в то время как значение строчной «а» равно 97.

Кстати, если хотите узнать уникальное значение какого-нибудь символа, используйте функцию ord: print(ord("A")) # 65

При сравнении символов или строк, Python конвертирует символы в их соответствующие порядковые значения, после чего сравнивает слева направо.

Существует функция chr, преобразовывающая порядковое значение в символ: print(chr(1040)) # 'A' Например, кириллическая А соответствует значению 1040. Есть свои значения у цифр, а также вспомогательных знаков, включая «?», «=», пробел и т.д.

Методы строк

Мы уже знакомы с некоторыми встроенными функциями: min(), max(), len(), int(), float() и т.д. Метод — специализированная функция, тесно связанная с объектом. Как и функция, метод вызывается для выполнения отдельной задачи, но он вызывается для определенного объекта и "знает" о своем целевом объекте во время выполнения.

Таким образом: метод — функция, применяемая к объекту. В данном случае к строке. Если же функция вызывается в виде имя_функции(параметры), то метод вызывается в виде имя_объекта.имя_метода(параметры). Например, s.find('e') — это применение к строке s метода find с одним параметром 'e'.

s.count(m) - считает количество непересекающихся вхождений подстроки m в строку s: s = 'foo goo moo'
print(s.count(('oo')) # 3
print(s.count(('a')) # 0

s.find(m) - ищет первое вхождение подстроки m в строке s. Если строка s не содержит подстроки m, то метод возвращает значение -1: s = 'foo bar foo baz foo qux'

print(s.find(('foo')) # 0
print(s.find(('bar')) # 4
print(s.find(('qu')) # 20
print(s.find(('python')) # -1

s.replace(m, n, count) - возвращает копию s со всеми вхождениями подстроки m, замененными на n count раз: s = 'foo baz foo qux'

print(s.replace('foo', 'grault')) # 'grault baz grault qux'
print(s.replace('foo', 'grault', 1)) # 'grault baz foo qux'

s.split(symb) - возвращает список, состоящий из подстрок строки s, разделённые символом symb, если не указать символ, то строка поделится по словам: s = 'foo baz foo qux'

print(s.split()) # ['foo', 'baz', 'foo', 'qux']
print(s.split("f")) # ['foo', 'baz', 'foo', 'qux']

Существует большая разница между результатами вызова методов s.split() и s.split(' '). Разница в поведении проявляется, когда строка содержит несколько пробелов между словами. s = 'Python is the most powerful language'
words1 = s.split()
words2 = s.split(' ')
print(words1) # ['Python', 'is', 'the', 'most', 'powerful', 'language']
print(words2)
# ['Python', '', '', '', 'is', '', '', 'the', '', 'most', '', 'powerful', '', 'language']

d.join(s) - соединяет элементы списка s с помощью разделителя (строки) d: words = ['Python', 'is', 'the', 'most', 'powerful', 'language']
s = ' '.join(words)
print(s) # 'Python is the most powerful language'
a = '_'.join(words)
print(a) # 'Python_is_the_most_powerful_language'