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

⏱ 20 мин · 🧩 заданий: 5

Кортеж

Кортеж (tuple) — неизменяемая упорядоченная последовательность.

point = (3, 4)
person = ("Анна", 28, "Москва")
single = (42,)          # кортеж из одного элемента — нужна запятая!
not_tuple = (42)        # это просто число в скобках
empty = ()
no_parens = 1, 2, 3     # кортеж создаёт запятая, скобки не обязательны
print(type(single), type(not_tuple), no_parens)
print(point[0], person[-1], person[1:], len(person))
print(person.count(28), person.index("Москва"))
point = (3, 4)
point[0] = 10           # TypeError: 'tuple' object does not support item assignment

Зачем кортежи, если есть списки

list tuple
Изменяемость да нет
Можно ключом словаря / в set нет да (если элементы хешируемы)
Типичный смысл однородная коллекция переменной длины фиксированная запись: каждая позиция имеет свой смысл
Память и скорость создания больше немного меньше и быстрее
# координаты как ключи словаря
distances = {(0, 0): 0, (3, 4): 5}
print(distances[(3, 4)])

# кортеж занимает меньше памяти
import sys
print(sys.getsizeof([1, 2, 3]), sys.getsizeof((1, 2, 3)))

На собеседовании

«Чем list отличается от tuple?» — изменяемость; хешируемость (ключи словаря); семантика (однородные данные против записи); кортеж немного компактнее и создаётся быстрее, константные кортежи компилятор хранит прямо в байткоде.

Распаковка

x, y = (3, 4)
name, age, city = ["Анна", 28, "Москва"]    # распаковывается любое итерируемое

first, *rest = [1, 2, 3, 4]
*init, last = "abcd"
head, *_, tail = range(10)                   # _ — «ненужная» переменная
print(first, rest, init, last, head, tail)

# вложенная распаковка
(x1, y1), (x2, y2) = [(0, 0), (3, 4)]
print(x2 - x1, y2 - y1)

# распаковка в цикле
for name, score in [("Аня", 90), ("Боря", 75)]:
    print(name, score)
a, b = [1, 2, 3]     # ValueError: too many values to unpack (expected 2)

Звёздочка при вызове и создании

def area(w, h):
    return w * h

size = (3, 4)
print(area(*size))             # распаковать кортеж в аргументы

a = [1, 2]
b = (3, 4)
print([*a, *b, 5], (*a, *b))   # склеить в новый список / кортеж

Неизменяемость «поверхностная»

t = (1, [2, 3])
t[1].append(4)          # список внутри изменяемый
print(t)
try:
    hash(t)
except TypeError as e:
    print("Не хешируется:", e)

Запустите 👣 Пошагово: кортеж хранит ссылку на список #2, и меняется именно список.

Именованные кортежи

Когда позиций много, person[2] становится непонятным. namedtuple даёт доступ по именам:

from collections import namedtuple
from typing import NamedTuple

Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
print(p.x, p.y, p, p[0])

class Employee(NamedTuple):      # современный синтаксис с аннотациями
    name: str
    salary: int = 100_000

e = Employee("Анна")
print(e, e._replace(salary=150_000), e._asdict())

Именованный кортеж остаётся кортежем: неизменяем, распаковывается, сравнивается. Для изменяемых записей используйте dataclass (урок в модуле ООП).

Итог

  • Кортеж — неизменяемая последовательность; создаёт его запятая: (42,).
  • Используйте для фиксированных записей, ключей словаря, возврата нескольких значений.
  • Распаковка: a, b = ..., first, *rest = ..., вложенная, в цикле; * при вызове функции.
  • Неизменяемость поверхностная: изменяемые объекты внутри меняются, и такой кортеж не хешируется.
  • namedtuple / typing.NamedTuple — кортеж с именованными полями.

Практика решено 0 из 5

Вы не вошли — ответы проверяются, но прогресс не сохранится. Войти или зарегистрироваться.
Задание 1 Один вариант ответа

Какой тип у x = (5) и у y = (5,)?

Задание 2 Программа на Python

Напишите функцию stats(nums), которая возвращает кортеж (минимум, максимум, среднее). Среднее округлите до 2 знаков.

Какие тесты проверяют код (3)
assert stats([1, 2, 3, 4]) == (1, 4, 2.5)
assert isinstance(stats([5]), tuple)
assert stats([2, 2, 3]) == (2, 3, 2.33)
Задание 3 Программа на Python

Используя распаковку со звёздочкой, напишите функцию head_tail(seq), которая возвращает кортеж (первый элемент, список остальных). head_tail([1, 2, 3]) → (1, [2, 3]).

Какие тесты проверяют код (3)
assert head_tail([1, 2, 3]) == (1, [2, 3])
assert head_tail("ab") == ("a", ["b"])
assert head_tail([7]) == (7, [])
Задание 4 Один вариант ответа

Можно ли изменить кортеж t = (1, [2, 3]) так, чтобы получилось (1, [2, 3, 4])?

Задание 5 Несколько вариантов

Где уместно использовать кортеж вместо списка?

Войдите, чтобы отмечать пройденные уроки.