Кортеж – тип данных, с которым вы будете сталкиваться регулярно: в словарях, в возвращаемых значениях функций, при работе с JSON и так далее. Кортежи во многом похожи на списки, но свои особенности у этого типа данных тоже есть – если вы не будете знать этих особенностей, то можете получить посреди кода ошибку, которую будет трудно отловить. Ниже – все о кортежах: что это, как их создавать и как ими манипулировать.
Зайдем немного издалека: почти любое приложение – это алгоритм, что-то делающий с данными, и эти данные нам нужно где-то хранить (примечание: исключением являются stateless-приложения, но они встречаются крайне редко). Простое и понятное место для хранения – переменные, с ними в Python все просто: кладем любое значение в переменную, достаем при необходимости.
Но переменные – не всегда удобно: если у вас есть имя, возраст и пол пользователя, вам бы хотелось хранить их в одном месте; 20 случайно сгенерированных чисел, необходимых вам для каких-то целей, тоже лучше было бы хранить в одной переменной, а не в 20 разных. Для таких задач есть структуры данных – некоторое выраженное командами языка соглашение, которое позволяет хранить в одном месте несколько единиц информации. Для многих ЯП самой базовой структурой языка является массив: четко ограниченная по вместимости последовательность данных одного типа. Например: [1,2,3,4,5] – массив целых чисел, хранящий до 5 элементов.
В Python базовая структура данных – список: изменяемая упорядоченная последовательность произвольной ширины, которая позволяет хранить любые элементы. Проще говоря: кладем что угодно в какой угодно последовательности, при необходимости обращаемся к элементу в конкретной позиции, если надо – добавляем/изменяем/удаляем элемент. Кортеж – это неизменяемая упорядоченная последовательность, которая позволяет хранить любые элементы. В чем разница:
Основное преимущество кортежей перед списками – кортежи и едят меньше памяти, и работают быстрее (более детально можно почитать здесь) за счет неизменяемости. Она же и составляет основной недостаток кортежа – если вам нужно хранить динамично меняющиеся данные, кортеж не подойдет. Вы будете часто встречать кортежи в возвращаемых значениях функций – Python позволяет вернуть из функции только одно значение, поэтому если нужно вернуть несколько, их обычно оборачивают в кортеж или словарь. Более редкое, но все еще важное применение – кортежи могут являться ключами списков, потому что они неизменяемы.
Самый простой способ создания кортежа – перечислением его элементов через запятую:
test_tuple = 1, 2, 3, 'a', 'b', 'c'
Элементы можно взять в скобки для наглядности, но это – не обязательно. Основной кейс, когда скобки обязательны – если мы помещаем кортеж в другой кортеж:
test_tuple = ((1, 2, 3), ('a', 'b', 'c'))
Второй случай, когда скобки обязательны – если мы создаем пустой кортеж:
test_tuple = ()
Если создаете кортеж с одним элементом – после элемента нужно поставить запятую, иначе интерпретатор присвоит переменной тип элемента:
test_tuple = 70,
Второй способ создания – с помощью встроенной функции tuple(). Она способна принимать на вход практически любые значения и формировать из них кортеж. Особенно она полезна тем, что в нее можно передать любой итерируемый объект, и он будет преобразован в кортеж:
Здесь же кроется и проблема – если вам нужно засунуть, например, строку в кортеж, вы не можете просто отдать ее функции tuple() – функция нарежет строку на символы. Придется выкручиваться, самый простой способ – создать пустой кортеж, после чего через «+» присоединить к нему кортеж со строкой:
С кортежами можно делать все то же самое, что и со списками (кроме модификации элементов):
Отдельно стоит упомянуть про упаковку и распаковку. С упаковкой мы уже познакомились – для того, чтобы упаковать значения в кортеж, вам нужно просто объединить их через запятую. Распаковка же – это когда мы распаковываем кортеж на отдельные переменные. Например, если у нас есть кортеж из 3 чисел, то распаковать его можно так:
Иногда случается так, что нам нужно распаковать не весь кортеж, а только часть его – в этом случае нужно использовать переменную, перед которой стоит «*», все нераспакованные переменные пойдут в нее. Эта переменная может стоять в начале, середине или конце распаковки, в выражении распаковки можно использовать только одну «*». Пример:
Обратите внимание, что переменная middle содержит список, а не кортеж.
Как и для многих вещей в Python, для кортежей в языке есть ряд встроенных функций, вот они:
Кортеж – это неизменяемая упорядоченная структура данных, в которой можно хранить элементы разных типов. Кортежи работают быстрее, чем списки. Часто их используют для передачи результата работы функции.
Можно просто перечислить элементы через запятую – они объединятся в кортеж (упаковка кортежа). Можно передать в функцию tuple() итерируемый объект – на его основе будет создан кортеж.
Официальная документация: 5. Data Structures — Python 3.13.3 documentation.
Когда вы, например, создаете кортеж и помещаете в него списки – вы на самом деле помещаете в него не сами списки, а ссылки на них. Ссылку вы изменить не можете, а вот список по ссылке – вполне себе можете, то есть код
list1 = [1,2,3]
list2 = [4,5,6]
test_tuple = list1, list2
test_tuple[0][0] = 5
print(test_tuple[0])
будет работать, на выходе вы получите [5, 2, 3].