Python 3. Кортежи
Свойства, индексация и срезы
Я уже писал про последовательности и множества
в Python 3. Кортеж (tuple) — это упорядоченная неизменяемая последовательность объектов. Простыми словами, это почти то же самое, что список
, только после создания его нельзя изменить: нельзя добавить, удалить или заменить элемент. Если нужен другой набор значений, создаётся новый кортеж.
Кортежи в Python 3 записываются в круглых скобках, например так:
Код:
my_tuple = (1, 2, 'три')
В коде выше мы создали кортеж (1, 2, ‘три’) и связали его с переменной my_tuple. Как видите, наш кортеж хранит и числа, и строки. Элементы в кортеже могут быть любого типа, в том числе разных.
Кортеж, так же как и список, нумерует (индексирует) свои элементы:

Индексация позволяет обращаться к объектам по индексу (положительному или отрицательному), а также создавать срезы. Нумерация с начала идёт с нуля, а с конца — с -1.
Получение некоторых свойств кортежа, обращение по индексам и создание срезов показано в примере ниже:
Код:
my_tuple = (1, 2, 3, 'четыре')
print('Тип объекта:', type(my_tuple))
print('Длина:', len(my_tuple))
print('Первый элемент:', my_tuple[0])
print('Последний элемент:', my_tuple[-1])
print('Срез [1:3]:', my_tuple[1:3])
print('Срез [0:3:2]:', my_tuple[0:3:2]) # С шагом 2
print('Срез [::-1]:', my_tuple[::-1]) # Кортеж в обратном порядке
Исполнение:
Тип объекта: <class 'tuple'>
Длина: 4
Первый элемент: 1
Последний элемент: четыре
Срез [1:3]: (2, 3)
Срез [0:3:2]: (1, 3)
Срез [::-1]: ('четыре', 3, 2, 1)
Запомните, когда вы создаёте срез, то указываете, от какого элемента (включительно) и до какого элемента (не включительно) нужно взять значения. Также можно указать шаг среза, например каждый второй элемент или каждый третий. Если указанная граница выходит за пределы кортежа, ошибки не будет: Python просто вернёт то, что есть. Именно поэтому срез [1:4] у кортежа из трёх элементов работает без проблем.
Срез всегда возвращает новый кортеж, а исходный остаётся без изменений.
Как создать кортеж
Кортеж можно создать несколькими способами.
Пустой кортеж создаётся пустыми скобками или функцией tuple():
Код:
empty1 = ()
empty2 = tuple()
print(empty1, type(empty1))
print(empty2, type(empty2))
Исполнение:
() <class 'tuple'>
() <class 'tuple'>
Кортеж из одного элемента создаётся с обязательной запятой. Это самая частая ошибка новичков. Дело в том, что просто скобки Python воспринимает как группировку выражения, а не как кортеж:
Код:
not_tuple = (5)
my_tuple = (5,)
print(type(not_tuple))
print(type(my_tuple))
Исполнение:
<class 'int'>
<class 'tuple'>
Получается, что кортеж создаёт именно запятая, а не скобки. Поэтому скобки можно и вовсе не писать:
Код:
my_tuple = 1, 2, 3
print(my_tuple)
print(type(my_tuple))
Исполнение:
(1, 2, 3)
<class 'tuple'>
Тем не менее я рекомендую всё же использовать скобки: так код читается лучше, и сразу видно, что это кортеж.
Преобразование в кортеж другой последовательности или итерируемого объекта делается функцией tuple():
Код:
print(tuple('abc'))
print(tuple([1, 2, 3]))
print(tuple(range(5)))
Исполнение:
('a', 'b', 'c')
(1, 2, 3)
(0, 1, 2, 3, 4)
Кортеж нельзя изменить
Если попытаться изменить элемент кортежа, Python выдаст ошибку TypeError:
Код:
my_tuple = (1, 2, 'три')
my_tuple[0] = 10
Исполнение:
TypeError: 'tuple' object does not support item assignment
Такая же ошибка будет при попытке удалить элемент (del my_tuple[0]). У кортежей также нет методов append(), remove(), sort() и других методов, которые меняют содержимое.
Работа с кортежами в Python
Точно так же как строки и списки, кортежи поддерживают конкатенацию (объединение) и повторение:
Код:
my_tuple1 = (1, 2, 'три')
my_tuple2 = (4, 5, 'шесть')
print(my_tuple1 + my_tuple2)
print(my_tuple1 * 3)
Исполнение:
(1, 2, 'три', 4, 5, 'шесть')
(1, 2, 'три', 1, 2, 'три', 1, 2, 'три')
В обоих случаях создаётся новый кортеж. Поэтому запись += для кортежей работает, но она не изменяет старый кортеж, а создаёт новый и связывает с ним переменную:
Код:
my_tuple = (1, 2)
my_tuple += (3,)
print(my_tuple)
Исполнение:
(1, 2, 3)
Также можем проверить, содержится ли элемент в кортеже:
Код:
my_tuple = (1, 2, 'три')
print(1 in my_tuple)
print(5 in my_tuple)
Исполнение:
True
False
У кортежей есть всего два собственных метода. Метод count() подсчитывает, сколько раз элемент встречается в кортеже, а метод index() возвращает индекс первого найденного элемента:
Код:
my_tuple = (1, 2, 5, 2, 7, 1, 2, 4, 0)
print(my_tuple.count(2))
print(my_tuple.index(7))
Исполнение:
3
4
Если элемента в кортеже нет, метод index() вызовет ошибку ValueError, поэтому перед его использованием можно проверить наличие элемента через in.
Для кортежей также работают встроенные функции len(), min(), max(), sum() и sorted(). Обратите внимание, что sorted() всегда возвращает список, а не кортеж:
Код:
numbers = (3, 1, 2)
print(min(numbers))
print(max(numbers))
print(sum(numbers))
print(sorted(numbers))
Исполнение:
1
3
6
[1, 2, 3]
Перебирать кортеж можно в цикле for, как и любую другую последовательность:
Код:
servers = ('pve1', 'pve2', 'pbs1')
for server in servers:
print(server)
Исполнение:
pve1
pve2
pbs1
Как «изменить» кортеж
Если всё-таки нужно изменить кортеж, его обычно превращают в список, вносят изменения, а затем превращают обратно в кортеж:
Код:
my_tuple = (1, 2, 3)
my_list = list(my_tuple) # Кортеж -> список
my_list.append(4) # Меняем список
my_tuple = tuple(my_list) # Список -> кортеж
print(my_tuple)
Исполнение:
(1, 2, 3, 4)
Важно понимать, что в итоге мы получили новый кортеж, а не изменили старый. Если вам приходится так делать часто, возможно, стоит сразу использовать список.
Распаковка кортежей
Одна из самых удобных возможностей кортежей — распаковка. Вы можете разложить элементы кортежа по отдельным переменным за одну строку:
Код:
my_tuple = (1, 2, 3)
a, b, c = my_tuple
print(a, b, c)
Исполнение:
1 2 3
Количество переменных слева должно совпадать с количеством элементов в кортеже, иначе будет ошибка ValueError. Если нужно забрать только часть элементов, а остальные собрать вместе, используют звёздочку. Остаток при этом попадёт в список:
Код:
my_tuple = (1, 2, 3)
a, *rest = my_tuple
print(a, rest)
Исполнение:
1 [2, 3]
Благодаря распаковке в Python можно поменять значения двух переменных местами без временной переменной. На самом деле в этой записи справа создаётся кортеж, а слева он распаковывается:
Код:
a = 1
b = 2
a, b = b, a
print(a, b)
Исполнение:
2 1
Ещё кортежи используют, когда функция должна вернуть несколько значений. Фактически функция возвращает один кортеж, который можно сразу распаковать:
Код:
def min_max(numbers):
return min(numbers), max(numbers)
result = min_max([4, 2, 9])
print(result)
lowest, highest = min_max([4, 2, 9])
print(lowest, highest)
Исполнение:
(2, 9)
2 9
Неизменяемость и вложенные объекты
Здесь есть один тонкий момент. Кортеж неизменяемый, но это относится только к самому кортежу: к набору объектов, которые в нём лежат, и к их порядку. Если внутри кортежа находится изменяемый объект, например список, то сам этот объект изменить можно:
Код:
my_tuple = (1, [2, 3])
my_tuple[1].append(4)
print(my_tuple)
Исполнение:
(1, [2, 3, 4])
Кортеж по-прежнему хранит те же самые два объекта, просто один из них (список) поменял своё содержимое. Поэтому, если вам нужна полная неизменяемость, внутри кортежа тоже должны быть неизменяемые объекты: числа, строки, другие кортежи.
Зачем нужны кортежи, если есть списки
Основных причин несколько:
- Защита от случайных изменений. Неизменяемость кортежей обеспечивает определённую степень целостности. Разработчик может быть уверен, что кортеж не изменится через ссылку где-то в другом месте программы. Для списков такой гарантии нет.
- Кортежи можно использовать как ключи словаря (и как элементы множества), если все их элементы тоже неизменяемые. Списки для этого не подходят.
- Кортежи занимают меньше памяти и немного быстрее создаются, чем списки. Для небольших программ разница незаметна, но при работе с большим количеством мелких наборов данных она ощутима.
- Смысл. Если вы видите кортеж, то сразу понимаете, что это фиксированный набор значений (например, координаты точки или пара «хост — порт»), а не коллекция, которая будет расти.
Пример использования кортежа в качестве ключа словаря:
Код:
cities = {
(55.75, 37.62): 'Москва',
(59.93, 30.34): 'Санкт-Петербург',
}
print(cities[(55.75, 37.62)])
Исполнение:
Москва
Если понравилась статья, подпишись на мой канал в VK или Telegram .