Урок курса
Кортеж и распаковка
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
Число в строке должно быть выведено без разделителей тысяч.
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Продолжить с сохранением прогресса
Перейдите к уроку в учебном кабинете.
