Распаковка кортежей в Python: x, y = point
Один кортеж — несколько переменных за один шаг: x, y = point. Классический обмен значений, звёздочка для остатка и почему распаковывать множества опасно.
Редакция Питоники
Кортеж из урока 11 — пачка значений. Доставать их по одному через point[0] и point[1] можно, но для пары и тройки есть путь короче: распаковка — одна строка раздаёт значения по переменным. Она встречается всюду: в циклах по словарям, в возврате из функций, в обмене значений.
Базовая распаковка
point = (2, 3)
x, y = point
print(x)
print(y)
print(x + y)
2 3 5
Слева — переменные через запятую, справа — кортеж. Значения разложились по порядку: первый элемент в x, второй в y. Скобки слева не нужны: x, y = point и (x, y) = point — одно и то же. Работает и прямой список значений: x, y = 4, 8 — справа собирается кортеж и тут же распаковывается.
Обмен значений одной строкой
a = 1
b = 2
a, b = b, a
print(a, b)
2 1
Классика: a, b = b, a меняет значения местами без временной переменной. Справа сначала собирается кортеж (2, 1) со старыми значениями, и только потом он распаковывается в a и b — поэтому значения не затирают друг друга.
Число переменных должно совпадать
Переменных слева должно быть ровно столько, сколько элементов справа: лишняя или недостающая переменная — это ValueError.
point = (2, 3)
x, y, z = point
print(x, y, z)
Traceback (most recent call last):
File "app.py", line 2, in <module>
x, y, z = point
^^^^^^^
ValueError: not enough values to unpack (expected 3, got 2)Сообщение читается легко: ждали три значения, пришли два. При лишних значениях формулировка симметрична: too many values to unpack (expected 2) — значений больше, чем переменных.
Звёздочка: остаток в список
sizes = (36, 38, 40, 42, 44)
first, *rest = sizes
print(first)
print(rest)
print(type(rest))
36 [38, 40, 42, 44] <class 'list'>
Звёздочка перед именем собирает всё лишнее в список — не в кортеж: rest оказался list. Это удобно для схемы «первый и остальные»: первый размер отдельно, остальные пачкой.
data = (1, 2, 3, 4, 5)
a, *mid, b = data
print(a, mid, b)
1 [2, 3, 4] 5
Крайние значения — по именам, середина — списком. Звёздочка может стоять только одна: две звёздочки в одном присваивании — синтаксическая ошибка ещё до запуска.
Распаковка других последовательностей
first, second = [10, 20]
a, b, c = 'кот'
x, y = range(2)
print(first + second)
print(a, b, c)
print(x, y)
30 к о т 0 1
Механизм один для всех последовательностей: строка распадается на символы, range — на числа. Именно поэтому работал цикл по словарю из урока 8 курса про словари: for name, price in prices.items() распаковывал каждую пару-кортеж.
pairs = ((1, 10), (2, 20))
for num, val in pairs:
print(num, val * 2)
1 20 2 40
Звёздочка при вызове функции
point = (2, 3)
print(*point)
print(point)
print(max(*point))
2 3 (2, 3) 3
Звёздочка в вызове разворачивает кортеж в отдельные аргументы: print(*point) — то же, что print(2, 3). Без звёздочки print напечатал бы кортеж целиком, со скобками и запятой. А max(*point) — то же, что max(2, 3): функция получила два аргумента.
| Запись | Что делает |
|---|---|
| x, y = point | элементы в переменные по порядку |
| a, b = b, a | обмен значений через временный кортеж |
| first, *rest = t | остаток собирается в список |
| a, *mid, b = t | края по именам, середина списком |
| print(*t) | распаковка при вызове функции |
Что дальше
Распаковка — входная дверь в идиомы функций: в уроке 14 функция научится возвращать несколько значений разом — кортежем, который вы уже умеете разбирать. А в уроке 15 у кортежа появятся имена полей: namedtuple.
Сначала предскажи ответ в голове — это главный навык программиста.
t = (5, 10)
x, y = t
x, y = y, x
print(x, y)
nums = (1, 2, 3, 4)
a, *b = nums
print(a)
print(len(b))
p = (1, 2, 3)
x, *mid, z = p
print(mid)
1. Что произойдёт при x, y = (1, 2, 3)?
2. Что делает a, b = b, a?
3. Какого типа rest после first, *rest = (1, 2, 3)?
4. Почему x, y = {3, 1} — плохая идея?
5. Чему эквивалентен вызов print(*point) при point = (2, 3)?
6. Сколько звёздочек может быть в одном присваивании?
7. Что попадёт в a после a, b, c = 'кот'?
8. Что происходит в for name, price in prices.items():?
Дан кортеж dims = (30, 15) — ширина и высота. Распакуйте его в w и h, выведите периметр 2 * (w + h), затем поменяйте значения местами и выведите их одной строкой через print(w, h).
Что такое распаковка кортежа?
Раздача элементов последовательности переменным за один шаг: x, y = point кладёт первый элемент в x, второй — в y. Скобки слева не нужны, работает и с прямым перечислением: x, y = 4, 8.
Урок 11: tuple — неизменяемый кортежСколько переменных нужно слева?
Ровно столько, сколько элементов справа: несовпадение даёт ValueError — too many values to unpack при лишних значениях, not enough values to unpack при нехватке. Остаток без строгого счёта собирает звёздочка.
Что делает звёздочка при распаковке?
Собирает остаток в список: first, *rest = (1, 2, 3, 4) даёт first = 1 и rest = [2, 3, 4]. В вызове функций звёздочка работает наоборот — разворачивает коллекцию в отдельные аргументы: print(*point).
Можно ли распаковать список или строку?
Да: распаковка работает с любой последовательностью — список, строка, range. Множества не стоит: их порядок не гарантирован, и в переменные попадёт непредсказуемый набор. Нужна определённость — сначала sorted.
Где ещё встречается распаковка?
В цикле по парам словаря: for name, price in prices.items(). В возврате из функций — функция возвращает кортеж, вызывающий код его распаковывает. И в присваивании через enumerate: for i, value in enumerate(items).
Понравился урок? Сошлитесь на него
«Переменных слева должно быть ровно столько, сколько элементов справа: лишняя или недостающая переменная — это ValueError.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что дальше
Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.
Что читать дальше
Множества · Урок 12
Кортеж против списка в Python: что и когда использовать
У обоих есть индексы, len и in, но список можно менять, а кортеж — нет. Четыре отличия: изменяемость, ключ словаря, память и правило выбора за три секунды.
Множества · Урок 14
Функция возвращает несколько значений: return с кортежем
Функция возвращает пару значений одной строкой: запятая в return собирает кортеж, распаковка раскладывает его по переменным. min и max за один проход, звёздочка для остатка.
Множества · Урок 15
namedtuple в Python: кортеж с именами полей
namedtuple даёт кортежу имена полей: p.x вместо p[0], читаемый repr и всё кортежное на месте — индексы, распаковка, сравнение. Шесть строк кода, и записи перестают быть наборами индексов.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
Циклы · Урок 10
zip в Python: несколько последовательностей параллельно
Два списка идут параллельно: имена и баллы, товары и цены. zip склеивает их в пары, цикл берёт по одной — без индексов и range(len(...)).
zip два списка pythonраспаковка кортежа python
Функции · Урок 10
*args в Python: сколько аргументов угодно
Функция, которой нельзя заранее сказать, сколько значений придет: два числа, пять или ни одного. Разбираем звёздочку: упаковку в кортеж и распаковку при вызове.
распаковка аргументов pythonзвёздочка в python
Множества · Урок 19
Задачи на кортежи Python: практика с решениями
Пять задач на кортежи из практики: точки и функции, максимум с минимумом одним вызовом, защита записей от правок, ходы как ключи словаря и сортировка по полю. Код, вывод, разбор.
python tuple задачи для начинающихpython сортировка кортежей по элементу