3.1. Строки, кортежи, списки

Рассмотрим упорядоченные коллекции, индексацию, методы и функции для их обработки.

В первом параграфе мы познакомились с таким типом данных, как строка (str). Мы умеем складывать строки, умножать их на число и даже сравнивать между собой.

Если рассмотреть строку детальнее, то она состоит из символов, каждый из которых стоит на своём месте. Другими словами, строка — упорядоченная последовательность (коллекция) символов.

Слово «коллекция» в Python применяется не только к строкам. Коллекциями в Python также называют типы данных, в которых можно хранить сразу несколько значений.

В упорядоченных коллекциях, к которым относится строка, каждое значение автоматически имеет свой номер — индекс. Индексация в коллекциях Python начинается со значения 0. При этом пробел, запятая, управляющие символы \n, \t и прочие тоже получают свой индекс в строке. Для доступа к определённому символу строки по индексу нужно указать его в квадратных скобках сразу после имени переменной.

Давайте создадим программу, которая выводит первый символ строки, введённой пользователем:

text = input()
print(text[0])

Если пользователь введёт пустую строку, то наша программа выдаст ошибку:

IndexError: string index out of range

В пустой строке нет символов, и программа вышла за пределы строки. Таким образом, нельзя получить значение по индексу, который за пределами строки. Перед обращением к символу строки по индексу можно проверять, не выходит ли он за пределы строки, используя известную нам функцию len следующим образом:

text = input("Введите строку: ")
i = int(input("Введите индекс символа: "))
if i < len(text):
    print(text[i])
else:
    print("Индекс выходит за пределы строки")

Давайте подумаем, как можно взять последний символ строки? Для этого нам потребуется воспользоваться функцией len:

text = input()
print(text[len(text) - 1])

Однако в Python можно упростить эту запись, убрав из неё функцию len. И тогда в качестве индекса просто будет использоваться отрицательное число:

text = input()
print(text[-1])

Таким образом, последний символ имеет индекс -1, предпоследний -2 и т. д.

Так как строка — упорядоченная коллекция, то можно пройти по этой коллекции в цикле, указав в качестве индекса итерируемую переменную цикла. Например, вывести на строке каждый символ введённой пользователем строки:

text = input()
for i in range(len(text)):
    print(text[i])

Существует и другой способ пройти по символам строки в цикле. Если не требуется на каждой итерации цикла знать индекс текущего символа, то цикл можно оформить следующим образом:

text = input()
for letter in text:
    print(letter)

При такой записи цикла программа проходит не по индексам строки, а непосредственно по её символам. Так, переменная letter на каждой итерации цикла принимает значение очередного символа строки text.

Если требуется совместить проход непосредственно по символам строки с определением индекса итерации, то можно воспользоваться функцией enumerate. Она возвращает пары значений — номер элемента коллекции и сам этот элемент. Эта функция удобна, когда нужно пройти именно по элементам коллекции, но при этом ещё и знать индекс каждого элемента.

text = input()
for i, letter in enumerate(text):
    print(f"{i}. {letter}")

Для строк в Python существует ещё одна полезная операция — срез (slice).

Срез позволяет взять часть строки, указав начальный и конечный индексы (конечный индекс не включается в диапазон). Также можно указать шаг, с которым срез будет взят (по умолчанию шаг 1). Например, в одном из прошлых параграфов мы аналогичным образом использовали функцию range.

Кроме того, в срезах можно использовать отрицательную индексацию. А если срез выходит за пределы строки, то программа не упадёт с ошибкой, а просто вернёт существующую часть строки.

Следующий пример показывает возможные варианты использования срезов:

text = "Привет, мир!"
print(text[8:11])
print(text[:6])
print(text[8:])
print(text[:])
print(text[::2])

Обратите внимание: строка является неизменяемой коллекцией. Это означает, что изменить отдельный символ строки нельзя.

Например, попытаемся в следующей программе изменить значение одного из символов строки:

word = "мир"
word[0] = "п"

Программа выдаст ошибку:

TypeError: 'str' object does not support item assignment

Мы уже знаем, что взаимодействовать с переменными в Python можно с помощью операций и функций. Рассмотрим ещё один способ взаимодействия — методы.

Методы похожи на функции, но вызываются не сами по себе, а для конкретной переменной. Для каждого типа данных есть свой набор методов. Чтобы вызвать метод, его нужно указать через точку после имени переменной. В круглых скобках после имени метода дополнительно можно обозначить аргументы (параметры) вызываемого метода, как это делаем с функциями.

Например, у строк есть метод islower(), который проверяет, что в строке не встречаются большие буквы, и возвращает в таком случае значение True, иначе — False:

print("а".islower())
print("A".islower())
True
False

В следующей таблице перечислены часто используемые методы строк и примеры их работы. Важный момент: методы строк не меняют исходную строку, а возвращают новое значение, которое можно сохранить в переменной.

str.capitalize()

Метод str.capitalize()
Описание Возвращает копию строки, у которой первая буква заглавная, а остальные приведены к строчным
Пример s = "hello, World!"
s.capitalize()
Результат Hello, world!

str.count(sub)

Метод str.count(sub)
Описание Возвращает количество неперекрывающихся вхождений подстроки sub. К примеру, если искать в строке «ААААА» неперекрывающиеся значения «АА», то первое вхождение будет «AAAAA». Второе — «AAAAA». Больше неперекрывающихся вхождений нет. Так, поиск последующих вхождений подстроки происходит с индекса, который следует за последним найденным вхождением
Пример s = "Hello, world!"
s.count("l")
Результат 3

str.endswith(suffix)

Метод str.endswith(suffix)
Описание Возвращает True, если строка оканчивается на подстроку suffix. Иначе возвращает False. suffix может быть кортежем проверяемых окончаний строки
Пример s = "Hello, world!"
s.endswith("world!")
Результат True

str.find(sub)

Метод str.find(sub)
Описание Возвращает индекс первого вхождения подстроки sub. Если подстрока не найдена, то возвращает -1
Пример s = "Hello, world!"
s.find("o")
Результат 4

str.index(sub)

Метод str.index(sub)
Описание Возвращает индекс первого вхождения подстроки sub. Вызывает исключение ValueError, если подстрока не найдена. Тема ошибок (исключений) будет разбираться на одном из следующих параграфов
Пример s = "Hello, world!"
s.index("o")
Результат 4

str.isalnum()

Метод str.isalnum()
Описание Возвращает True, если все символы строки являются буквами и цифрами и в строке есть хотя бы один символ. Иначе возвращает False
Пример s = "abc123"
s.isalnum()
Результат True

str.isalpha()

Метод str.isalpha()
Описание Возвращает True, если все символы строки являются буквами и в строке есть хотя бы один символ. Иначе возвращает False
Пример s = "Letters"
s.isalpha()
Результат True

str.isdigit()

Метод str.isdigit()
Описание Возвращает True, если все символы строки являются цифрами и в строке есть хотя бы один символ. Иначе возвращает False
Пример s = "123"
s.isdigit()
Результат True

str.islower()

Метод str.islower()
Описание Возвращает True, если все буквы в строке маленькие и в строке есть хотя бы одна буква. Иначе возвращает False
Пример s = "word123"
s.islower()
Результат True

str.isupper()

Метод str.isupper()
Описание Возвращает True, если все буквы в строке большие и в строке есть хотя бы одна буква. Иначе возвращает False
Пример s = "WORD123"
s.isupper()
Результат True

str.join(str_col)

Метод str.join(str_col)
Описание Возвращает строку, полученную конкатенацией (сложением) строк — элементов коллекции str_col (обозначение коллекции с элементами типа данных «строка»). Разделителем является строка, для которой вызван метод
Пример a = ["1", "2", "3"]
"; ".join(a)
Результат "1; 2; 3"

str.ljust(width, fillchar)

Метод str.ljust(width, fillchar)
Описание Возвращает строку длиной width с выравниванием по левому краю. Строка дополняется справа символами fillchar до требуемой длины. По умолчанию значение fillchar — пробел
Пример s = "text"
s.ljust(10, "=")
Результат "text======"

str.lower()

Метод str.lower()
Описание Возвращает копию строки, у которой все буквы приведены к нижнему регистру
Пример s = "Hello, World!"
s.lower()
Результат "hello, world!"

str.lstrip(chars)

Метод str.lstrip(chars)
Описание Возвращает строку, у которой в начале удалены символы, встречающиеся в строке chars. Если значение chars не задано, то пробельные символы удаляются
Пример s = "BCCAstring"
s.lstrip("ABC")
Результат "string"

str.rstrip(chars)

Метод str.rstrip(chars)
Описание Возвращает строку, у которой в конце удалены символы, встречающиеся в строке chars. Если значение chars не задано, то пробельные символы удаляются
Пример s = "stringBCCA"
s.rstrip("ABC")
Результат "string"

str.split(sep)

Метод str.split(sep)
Описание Возвращает список строк по разделителю sep. По умолчанию sep — любое количество пробельных символов
Пример s = "one, two, three"
s.split(", ")
Результат ["one", "two", "three"]

str.startswith(prefix)

Метод str.startswith(prefix)
Описание Возвращает True, если строка начинается на подстроку prefix, иначе возвращает False. prefix может быть кортежем проверяемых префиксов строки. Под кортежами подразумевается неизменяемая последовательность элементов
Пример s = "Hello, world!"
s.startswith("Hello")
Результат True

str.strip(chars)

Метод str.strip(chars)
Описание Возвращает строку, у которой в начале и в конце удалены символы, встречающиеся в строке chars. Если значение chars не задано, то пробельные символы удаляются
Пример s = "abc Hello, world! cba"
s.strip(" abc")
Результат "Hello, world!"

str.title()

Метод str.title()
Описание Возвращает строку, в которой каждое отдельное слово начинается с буквы в верхнем регистре, а остальные буквы идут в нижнем
Пример s = "hello, world!"
s.title()
Результат "Hello, World!"

str.upper()

Метод str.upper()
Описание Возвращает копию строки, у которой все буквы приведены к верхнему регистру
Пример s = "Hello, world!"
s.upper()
Результат "HELLO, WORLD!"

str.zfill(width)

Метод str.zfill(width)
Описание Возвращает строку, дополненную слева символами «0» до длины width
Пример s = "123"
s.zfill(5)
Результат "00123"

Рассмотрим ещё одну коллекцию в Python — список (list). Этот тип данных является упорядоченной коллекцией, которая может в качестве элементов иметь значения любого типа данных.

Один из способов создания списков — перечислить его элементы в квадратных скобках и присвоить это значение переменной, которая и станет в итоге списком в программе:

numbers = [10, 20, 30]

В примере мы создали список, состоящий из трёх элементов — целых чисел. Список может хранить значения любого типа, поэтому можно создать список со следующими элементами:

mixed_list = [10, 20.55, "text"]

Индексация в списках работает так же, как и в строках, — начальный индекс 0. Можно использовать отрицательные индексы, а также доступны срезы:

numbers = [10, 20, 30, 40, 50]
print(numbers[0])
print(numbers[-1])
print(numbers[1:3])
print(numbers[::-1])

Результат работы программы:

10
50
[20, 30]
[50, 40, 30, 20, 10]

В отличие от строки, список относится к изменяемой коллекции. У списка можно изменить отдельный элемент, добавить новые или удалить существующие. Для изменения существующего элемента нужно указать его в левой части операции присваивания, а в правой указать новое значение этого элемента:

numbers = [10, 20, 50]
numbers[2] = 30
print(numbers)

Вывод программы:

[10, 20, 30]

Если требуется добавить элемент в конец списка, то можно использовать метод append().

Например, напишем программу, в которой список последовательно заполняется 10 целочисленными значениями с клавиатуры:

numbers = []
for i in range(10):
    numbers.append(int(input()))
print(numbers)

Вывод программы:

[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

Для удаления элемента из списка применяется операция del. Нужно указать индекс элемента, который требуется удалить:

numbers = [10, 20, 50]
del numbers[-1]
print(numbers)

Вывод программы:

[10, 20]

С помощью del можно удалить несколько элементов списка. Для этого вместо одного элемента указываем срез:

numbers = [1, 2, 3, 4, 5]
del numbers[::2]
print(numbers)

Вывод программы:

[2, 4]

Полезные методы и функции списков и примеры их работы приведены в следующей таблице.

Операция

Описание

Пример

Результат

x in s

Возвращает True, если в списке s есть элемент x. Иначе False

1 in [1, 2, 3]

True

x not in s

Возвращает False, если в списке s есть элемент x. Иначе True

4 not in [1, 2, 3]

True

s + t

Возвращает список, полученный конкатенацией списков s и t

[1, 2] + [3, 4, 5]

[1, 2, 3, 4, 5]

s * n (n * s)

Возвращает список, полученный дублированием n раз списка s

[1, 2, 3] * 3

[1, 2, 3, 1, 2, 3, 1, 2, 3]

len(s)

Возвращает длину списка s

len([1, 2, 3])

3

min(s)

Возвращает минимальный элемент списка

min([1, 2, 3])

1

max(s)

Возвращает максимальный элемент списка

max([1, 2, 3])

3

s.index(x)

Возвращает индекс первого найденного элемента x. Вызывается исключение ValueError, если элемент не найден

[1, 2, 3, 2, 1].index(2)

1

s.count(x)

Возвращает количество элементов x

[1, 1, 1, 2, 3, 1].count(1)

4

s.append(x)

Добавляет элемент x в конец списка

s = [1, 2]
s.append(3)
print(s)

[1, 2, 3]

s.clear()

Удаляет все элементы списка

s = [1, 2, 3]
s.clear()
print(s)

[]

s.copy()

Возвращает копию списка

[1, 2, 3].copy()

[1, 2, 3]

s.extend(t) или s += t

Расширяет список s элементами списка t

s = [1, 2, 3]
s.extend([4, 5])
print(s)

[1, 2, 3, 4, 5]

s.insert(i, x)

Вставляет элемент x в список по индексу i

s = [1, 3, 4]
s.insert(1, 2)
print(s)

[1, 2, 3, 4]

s.pop(i)

Возвращает и удаляет элемент с индексом i. Если i не указан, то возвращается и удаляется последний элемент

s = [1, 2, 3]
x = s.pop()
print(x)
print(s)

3
[1, 2]

s.remove(x)

Удаляет первый элемент со значением x

s = [1, 2, 3, 2, 1]
s.remove(2)
print(s)

[1, 3, 2, 1]

s.reverse()

Меняет порядок элементов списка на противоположный (переворачивает список)

s = [1, 2, 3]
s.reverse()
print(s)

[3, 2, 1]

s.sort()

Сортирует список по возрастанию, меняя исходный список. Для сортировки по убыванию используется дополнительный аргумент reverse=True

s = [2, 3, 1]
s.sort()
print(s)

[1, 2, 3]

sorted(s)

Возвращает отсортированный по возрастанию список, не меняя исходный. Для сортировки по убыванию используется дополнительный аргумент reverse=True

s = [2, 3, 1]
new_s = sorted(s, reverse=True)
print(new_s)

[3, 2, 1]

Ещё одной коллекцией в Python является кортеж (tuple). Кортеж является неизменяемой упорядоченной коллекцией. В кортеже нельзя заменить значение элемента, добавить или удалить элемент. Простыми словами, кортеж — неизменяемый список. Свойство неизменяемости используется для защиты от случайных или намеренных изменений.

Задать кортеж можно следующим образом:

numbers = (1, 2, 3, 4, 5)

Если нужно создать кортеж из одного элемента, то запись будет такой:

one_number = (1, )

Запятая в примере показывает, что в скобках не совершается операция, а идёт перечисление элементов кортежа.

Для кортежей доступны те операции и методы списков, которые не изменяют исходный кортеж.

В качестве примера использования кортежей приведём программу для обмена значений двух переменных:

a = 1
b = 2
(a, b) = (b, a)
# можно опустить круглые скобки и записать так a, b = b, a
print(f"a = {a}, b = {b}")

Вывод программы:

a = 2, b = 1

Между коллекциями можно производить преобразования. Покажем их на примере преобразования строки в список и кортеж (элементы строки, символы становятся элементами списка и кортежа соответственно):

text = "Привет, мир!"
list_symbols = list(text)
tuple_symbols = tuple(text)
text_from_list = str(list_symbols)
print(list_symbols)
print(tuple_symbols)
print(text_from_list)

Вывод программы:

['П', 'р', 'и', 'в', 'е', 'т', ',', ' ', 'м', 'и', 'р', '!']
('П', 'р', 'и', 'в', 'е', 'т', ',', ' ', 'м', 'и', 'р', '!')
['П', 'р', 'и', 'в', 'е', 'т', ',', ' ', 'м', 'и', 'р', '!']

Обратите внимание: преобразование коллекций к типу данных str не объединяет элементы этой коллекции в одну строку, а возвращает представление коллекции в виде строки.

Отмечайте параграфы как прочитанные чтобы видеть свой прогресс обучения

Вступайте в сообщество хендбука

Здесь можно найти единомышленников, экспертов и просто интересных собеседников. А ещё — получить помощь или поделиться знаниями.
Вступить
Сообщить об ошибке
Предыдущий параграф2.4. Вложенные циклы

Тут — разберёмся, что такое вложенные циклы, а также как пользоваться флагами и операторами break и continue.

Следующий параграф3.2. Множества, словари

А здесь — неупорядоченные коллекции, методы и функции для их обработки.