Урок курса

Кортеж и распаковка

Python для новичков

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

Кортеж: создание литералом и доступ по индексу

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

point = (3, 7)
coords = (10, 20, 30)

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

pair = 1, 2
print(type(pair))  # <class 'tuple'>

Однако на практике скобки почти всегда пишут: они делают код читаемым с первого взгляда.

Читать элементы кортежа можно по индексу — ровно так же, как в списке. Индексация начинается с нуля, отрицательные индексы отсчитываются с конца:

coords = (10, 20, 30)
print(coords[0])   # 10
print(coords[1])   # 20
print(coords[-1])  # 30

Чтобы узнать длину кортежа, используют len() — всё как со списком:

print(len(coords))  # 3

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

profile = ('Анна', 25, True)
print(profile[0])  # Анна
print(profile[2])  # True

Тип данных в Python для кортежа называется tuple. Если нужно убедиться, что переменная действительно кортеж, type() вернёт именно это:

print(type(coords))  # <class 'tuple'>

Пока всё выглядит знакомо: индексы, len(), смешанные типы — это всё есть и в списке. Принципиальная разница проявится в следующем разделе, когда попробуем что-то изменить.

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

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

Попробуем написать то, что для списка было бы абсолютно нормальной операцией:

t = (1, 2, 3)
t[0] = 99  # попытка изменить первый элемент

Python немедленно ответит ошибкой:

TypeError: 'tuple' object does not support item assignment

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

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

t = (1, 2, 3)
t.append(4)  # AttributeError: 'tuple' object has no attribute 'append'
t.remove(1)  # AttributeError: 'tuple' object has no attribute 'remove'

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

Читать элементы по индексу по-прежнему можно — неизменяемость касается только операций записи:

print(t[0])  # 1 — чтение работает

Зачем тогда вообще нужен кортеж, если он так ограничен? Именно поэтому и нужен. Когда данные не должны меняться — координаты точки, пара «имя—значение», фиксированный набор параметров — кортеж сигнализирует об этом явно. Если кто-то прочитает ваш код и увидит кортеж, он сразу понимает: эти данные неизменны по замыслу.

Кортеж — это не «сломанный список». Это другой инструмент с другой гарантией: содержимое не изменится, что бы с ним ни делали дальше.

Распаковка кортежа в переменные

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

person = ('Анна', 25, 'Москва')
name, age, city = person
print(name)  # Анна
print(age)   # 25
print(city)  # Москва

Python берёт элементы кортежа слева направо и присваивает каждый из них соответствующей переменной слева от =. Первый элемент уходит в name, второй — в age, третий — в city. Всё происходит за одно выражение.

То же самое работает, если кортеж создан прямо в строке распаковки:

x, y = (3, 7)
print(x)  # 3
print(y)  # 7

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

Условие корректности: число переменных должно совпадать с числом элементов.

Если переменных больше или меньше, Python выбросит ValueError:

a, b = (1, 2, 3)  # слишком много значений
ValueError: too many values to unpack (expected 2)
a, b, c = (1, 2)  # слишком мало значений
ValueError: not enough values to unpack (expected 3, got 2)

Ошибка возникает потому, что Python не знает, куда деть лишнее значение или откуда взять недостающее.

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

ValueError чаще всего возникает из-за опечатки: написали две переменные вместо трёх, или перепутали порядок. Если такая ошибка появилась, достаточно пересчитать элементы кортежа и скорректировать список переменных слева.

Полный цикл: от создания кортежа до распаковки

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

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

# Шаг 1: создаём кортеж литералом
flight = ('SU101', 'JFK', 540)

# Шаг 2: читаем элементы по индексу, чтобы убедиться в содержимом
print(flight[0])   # SU101
print(flight[1])   # JFK
print(flight[-1])  # 540

# Шаг 3: распаковываем
code, destination, duration = flight

# Шаг 4: используем переменные
print(f'Рейс {code} летит в {destination}, время в пути — {duration} минут')
# Рейс SU101 летит в JFK, время в пути — 540 минут

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

После распаковки code, destination и duration — обычные переменные. С ними можно делать всё что угодно: считать, сравнивать, передавать в функции. Сам кортеж flight при этом никуда не делся и не изменился.

Важный момент: распаковка не разрушает кортеж. После строки code, destination, duration = flight переменная flight по-прежнему содержит весь кортеж целиком:

print(flight)  # ('SU101', 'JFK', 540)

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

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

Задача 1

Допишите одну строку создания кортежа point, чтобы последующая распаковка работала и переменные получили значения 5 и 10:

# ваша строка
x, y = point

Ответ должен начинаться с point =.

Без регистрации · результат не сохраняется

Задача 2

Программист написал следующий код:

point = (3, 7)
point[0] = 10

Что произойдёт при его выполнении?

Выберите один вариант
Без регистрации · результат не сохраняется

Задача 3

Какие значения окажутся в переменных r, g и b после распаковки?

rgb = (255, 128, 0)
r, g, b = rgb

Напишите три значения через запятую (например: 1, 2, 3).

Без регистрации · результат не сохраняется

Задача 4

Что произойдёт при выполнении этого кода?

data = (100, 200, 300)
first, second = data
Выберите один вариант
Без регистрации · результат не сохраняется

Задача 5

Какой тип получит переменная point после выполнения этого кода?

point = 10, 20
Выберите один вариант
Без регистрации · результат не сохраняется

Задача 6

Распакуй кортеж с данными о городе

В коде уже задан кортеж city_info с тремя значениями: названием города, численностью населения и страной.

Распакуйте этот кортеж в три переменные: name, population, country.

Затем сформируйте строку и сохраните её в переменную result в таком виде:

Город: Москва, страна: Россия, население: 12000000

Число в строке должно быть выведено без разделителей тысяч.

РешениеPython

Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.

Отправьте решение, чтобы увидеть результаты тестов.

Продолжить с сохранением прогресса

Перейдите к уроку в учебном кабинете.

Перейти к интерактивному уроку