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

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

Ключевые вопросы статьи

  • Что такое коллекции в Python и какие из них — упорядоченными?
  • Как обращаться к элементам строки, списка и кортежа по индексу?
  • Чем отличаются строки, списки и кортежи между собой?
  • Какие методы существуют для работы со строками и списками?
  • Как создавать срезы и преобразовывать одни коллекции в другие?

Упорядоченные коллекции: строки, списки и кортежи

Начнём с уже знакомой строки (str) и посмотрим на неё как на коллекцию — последовательность символов, к которой можно обращаться по индексам. А затем перейдём к другим упорядоченным структурам: спискам и кортежам. Они позволяют хранить сразу несколько значений — и во многом похожи на строки, но с важными отличиями.

Что такое коллекции и индексация

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

Слово «коллекция» в Python используется для обозначения типов данных, которые могут хранить сразу несколько значений. Строка — лишь один из таких типов. Помимо неё, к упорядоченным коллекциям относятся списки (list) и кортежи (tuple).

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

В Python индексация начинается с нуля. Это значит, что:

  • первый элемент имеет индекс 0,
  • второй — индекс 1,
  • и так далее.

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

Обращение к элементам по индексу

Чтобы получить символ строки по индексу, нужно указать этот индекс в квадратных скобках сразу после переменной:

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

Если пользователь введёт, например, Привет, программа выведет П — первый символ строки.

Но если строка окажется пустой, то возникнет ошибка:

IndexError: string index out of range

Это значит, что мы обратились к символу, которого не существует. Чтобы избежать этой ошибки, стоит заранее проверить, входит ли индекс в допустимые границы — например, с помощью функции len():

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

Отрицательная индексация

Допустим, мы хотим получить последний символ строки. Один из способов — использовать len():

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

Однако в Python есть более удобный способ: отрицательная индексация. Последний элемент строки имеет индекс -1, предпоследний — -2, и так далее:

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

Такой способ часто используется, когда нужно обратиться к символам с конца строки.

Проход по коллекциям

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

В этом разделе мы рассмотрим три способа прохода по элементам коллекции:

  • по индексам,
  • по значениям,
  • по индексам и значениям одновременно (с помощью функции enumerate()).

Цикл по индексам

Если нам важно знать индекс каждого элемента, можно пройти по коллекции с помощью цикла for и функции range(). Например, выведем по символу строки на каждой строке:

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

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

Цикл по значениям

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

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

Здесь переменная letter на каждой итерации принимает значение следующего символа строки. Такой цикл читается проще и используется чаще всего, если нам не нужен номер элемента.

Цикл с enumerate

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

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

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

Срезы

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

Срез позволяет удобно извлекать фрагмент коллекции, не прибегая к циклам и дополнительным условиям.

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

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

коллекция[начало:конец:шаг]

  • начало — индекс, с которого начать (включительно);
  • конец — индекс, до которого взять (не включается!);
  • шаг — через сколько элементов двигаться (по умолчанию 1).

Любой из параметров можно опустить. Например:

  • text[:5] — первые 5 символов;
  • text[::2] — каждый второй символ;
  • text[::-1] — строка в обратном порядке.

Также, как и при обычной индексации, здесь работает отрицательная индексация — можно отсчитывать с конца строки.

Важно

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

Примеры срезов

Рассмотрим разные варианты срезов:

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

Результат:

мир
Привет
мир!
Привет, мир!
Пие,мр

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

Работа со строками и списками

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

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

Неизменяемость строк

Попробуем изменить первый символ строки:

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

Результат:

TypeError: 'str' object does not support item assignment

Ошибка возникает потому, что строки нельзя менять «на месте». Если нужно изменить строку, необходимо создать новую — например, с помощью срезов, операций или методов.

Методы строк

Ранее мы использовали встроенные функции. Методы — это похожий инструмент, но они «принадлежат» конкретному типу данных. У строк есть собственный набор методов, которые вызываются через точку после переменной:

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

Метод islower() возвращает True, если все буквы в строке — строчные. Таких методов у строк много — и они не изменяют исходную строку, а возвращают новую. Если нужно сохранить результат, его следует присвоить переменной.

Ниже — подборка часто используемых методов строк с описаниями и примерами. Эти методы позволяют выполнять самые разные операции: изменять регистр, искать подстроки, форматировать текст и многое другое.

Примечание

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

str.capitalize()

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

Пример:

 s = "hello, World!"
 s.capitalize()

Результат:

Hello, world!
str.count(sub)

Описание
Возвращает количество неперекрывающихся вхождений подстроки sub. К примеру, если искать в строке «ААААА» неперекрывающиеся значения «АА», то первое вхождение будет «AAAAA». Второе — «AAAAA». Больше неперекрывающихся вхождений нет. Так, поиск последующих вхождений подстроки происходит с индекса, который следует за последним найденным вхождением

Пример:

s = "Hello, world!"
s.count("l")

Результат:

3
str.endswith(suffix)

Описание
Возвращает True, если строка оканчивается на подстроку suffix. Иначе возвращает False. suffix может быть кортежем проверяемых окончаний строки

Пример:

s = "Hello, world!"
s.endswith("world!")

Результат:

True
str.find(sub)

Описание
Возвращает индекс первого вхождения подстроки sub. Если подстрока не найдена, то возвращает -1

Пример:

s = "Hello, world!"
s.find("o")

Результат:

4
str.index(sub)

Описание
Возвращает индекс первого вхождения подстроки sub. Вызывает исключение ValueError, если подстрока не найдена. Тема ошибок (исключений) будет разбираться в одной из следующих статей

Пример:

 s = "Hello, world!"
 s.index("o")

Результат:

4
str.isalnum()

Описание
Возвращает True, если все символы строки являются буквами и цифрами и в строке есть хотя бы один символ. Иначе возвращает False

Пример:

s = "abc123"
s.isalnum()

Результат:

True
str.isalpha()

Описание
Возвращает True, если все символы строки являются буквами и в строке есть хотя бы один символ. Иначе возвращает False

Пример:

s = "Letters"
s.isalpha()

Результат:

True
str.isdigit()

Описание
Возвращает True, если все символы строки являются цифрами и в строке есть хотя бы один символ. Иначе возвращает False

Пример:

s = "123"
s.isdigit()

Результат:

True
str.islower()

Описание
Возвращает True, если все буквенные символы строки написаны строчными буквами. Иначе возвращает False

Пример:

s = "word123"
s.islower()

Результат:

True
str.isupper()

Описание
Возвращает True, если все буквы в строке большие и в строке есть хотя бы одна буква. Иначе возвращает False

Пример:

s = "WORD123"
s.isupper()

Результат:

True
str.join(str_col)

Описание
Возвращает строку, полученную конкатенацией (сложением) строк — элементов коллекции str_col (обозначение коллекции с элементами типа данных «строка»). Разделителем является строка, для которой вызван метод.

Пример:

a = ["1", "2", "3"]
"; ".join(a)

Результат:

"1; 2; 3"
str.ljust(width, fillchar)

Описание
Возвращает строку длиной width с выравниванием по левому краю. Строка дополняется справа символами fillchar до требуемой длины. По умолчанию значение fillchar — пробел

Пример:

s = "text"
s.ljust(10, "=")

Результат:

"text======"
str.lower()

Описание
Возвращает копию строки, у которой все буквы приведены к нижнему регистру

Пример:

s = "Hello, World!"
s.lower()

Результат:

"hello, world!"
str.lstrip(chars)

Описание
Возвращает строку, у которой в начале удалены символы, встречающиеся в строке chars. Если значение chars не задано, то пробельные символы удаляются

Пример:

s = "BCCAstring"
s.lstrip("ABC")

Результат:

"string"
str.rstrip(chars)

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

Пример:

s = "stringBCCA"
s.rstrip("ABC")

Результат:

"string"
str.split(sep)

Описание
Возвращает список строк по разделителю sep. По умолчанию sep — любое количество пробельных символов

Пример:

s = "one, two, three"
s.split(", ")

Результат:

["one", "two", "three"]
str.startswith(prefix)

Описание
Возвращает True, если строка начинается на подстроку prefix, иначе возвращает False. prefix может быть кортежем проверяемых префиксов строки. Под кортежами подразумевается неизменяемая последовательность элементов

Пример:

s = "Hello, world!"
s.startswith("Hello")

Результат:

True
str.strip(chars)

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

Пример:

s = "abc Hello, world! cba"
s.strip(" abc")

Результат:

"Hello, world!"
str.title()

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

Пример:

s = "hello, world!"
s.title()

Результат:

"Hello, World!"
str.upper()

Описание
Возвращает копию строки, у которой все буквы приведены к верхнему регистру

Пример:

s = "Hello, world!"
s.upper()

Результат:

"HELLO, WORLD!"
str.zfill(width)

Описание
Возвращает строку, дополненную слева символами «0» до длины width

Пример:

s = "123"
s.zfill(5)

Результат:

"00123"

Списки: изменяемые коллекции

Список (list) — ещё один важный тип коллекции в 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])

Изменение и удаление элементов

В отличие от строк, списки — изменяемые. Это значит, что элементы в них можно заменять, удалять или добавлять новые.

Чтобы изменить элемент, достаточно указать его индекс:

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]

Кортежи: неизменяемые списки

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

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

Основные свойства

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

Примеры создания:

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

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

one_number = (1, )

Примечание

При создании кортежа из одного элемента необходима запятая. Без неё Python воспримет запись как обычное выражение в скобках, а не как коллекцию.

Для кортежей доступны только те операции и методы, которые не изменяют коллекцию: доступ по индексу, срезы, проверка вхождения, функции len(), count(), index().

Примеры использования

Кортежи удобно использовать, когда нужно временно объединить значения. Например, для обмена значениями двух переменных:

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

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

a = 2, b = 1

Преобразование между коллекциями

Иногда нужно представить одну коллекцию в виде другой — например, превратить строку в список символов или в кортеж. В Python это можно сделать с помощью встроенных функций list(), tuple() и str().

Примеры преобразования

В этом примере мы преобразуем строку в список и кортеж. Каждый символ строки становится отдельным элементом новой коллекции:

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() не объединяет элементы в одну строку, а возвращает строковое представление коллекции. Если вы хотите собрать строку обратно из символов, используйте метод '.join(...)'.

Что дальше

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

В следующей статье вы узнаете:

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

После этого вы сможете создавать программы, которые быстро ищут, группируют и обрабатывают данные — без лишнего кода и проверок.

Ключевые выводы статьи

  • Строки, списки и кортежи — это упорядоченные коллекции, к элементам которых можно обращаться по индексу.
  • Строки и кортежи неизменяемы, списки — изменяемые.
  • Все три типа поддерживают срезы и перебор в цикле.
  • У строк и списков есть полезные методы, которые не изменяют исходную коллекцию, а возвращают новое значение.
  • Коллекции можно преобразовывать друг в друга с помощью функций list(), tuple() и str().