Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Когда использовать кортежи в Python: Полное руководство
Кортежи (tuples) — это иммутабельные (неизменяемые) коллекции, которые часто недооценивают. Вот практические сценарии использования.
1. Ключи в словарях
Кортежи хешируемы, поэтому могут быть ключами словаря:
# Матрица координат
grid = {
(0, 0): "A",
(0, 1): "B",
(1, 0): "C",
(1, 1): "D"
}
print(grid[(0, 1)]) # B
# Параметры функции как ключ (для кеширования)
cache = {}
def expensive_func(a, b, c):
key = (a, b, c)
if key not in cache:
cache[key] = compute(a, b, c)
return cache[key]
2. Элементы множества (set)
Уникальные неизменяемые комбинации:
# Уникальные пары
visited_transitions = set()
for event in events:
transition = (event.from_state, event.to_state)
if transition not in visited_transitions:
visited_transitions.add(transition)
log_new_transition(transition)
# Пример: избегание дубликатов
pairs = [(1, 2), (2, 3), (1, 2), (3, 4)]
unique_pairs = set(pairs)
print(unique_pairs) # {(1, 2), (2, 3), (3, 4)}
3. Защита от случайных изменений
Если функция должна вернуть неизменяемые данные:
# API должен гарантировать, что данные не изменятся
def get_rgb_colors():
return {
'red': (255, 0, 0),
'green': (0, 255, 0),
'blue': (0, 0, 255)
}
colors = get_rgb_colors()
# Даже если попытаемся изменить — ошибка
# colors['red'][0] = 200 # TypeError
# Это гарантирует консистентность в функции
def process_color(rgb):
# Функция уверена, что rgb не изменится
r, g, b = rgb
return (r + g + b) // 3
4. Возврат нескольких значений из функции
Натуральный и элегантный способ:
def parse_datetime(date_string):
"""Возвращает (дата, время, часовой пояс)"""
parts = date_string.split('T')
date = parts[0]
time_and_tz = parts[1].split('+')
time = time_and_tz[0]
tz = time_and_tz[1] if len(time_and_tz) > 1 else 'UTC'
return (date, time, tz)
date, time, tz = parse_datetime("2026-03-22T14:30:00+03:00")
print(f"Дата: {date}, Время: {time}, Зона: {tz}")
# С распаковкой
result = parse_datetime("2026-03-22T14:30:00+03:00")
print(result) # ('2026-03-22', '14:30:00', '03:00')
5. Неявное присваивание в циклах
Распаковка при итерации:
# Список кортежей
students = [
("Alice", 85),
("Bob", 92),
("Charlie", 78)
]
# Распаковка в цикле
for name, score in students:
print(f"{name}: {score}%")
# С индексом
for i, (name, score) in enumerate(students):
print(f"{i}. {name}: {score}%")
# Со словарями
for key, value in {"x": 10, "y": 20}.items():
print(f"{key} = {value}")
6. Аргументы функции через распаковку
# Функция ждёт 3 параметра
def greet(greeting, name, punctuation):
return f"{greeting} {name}{punctuation}"
# Распаковка кортежа
args = ("Hello", "Alice", "!")
print(greet(*args)) # Hello Alice!
# Практический пример
db_params = ("localhost", 5432, "mydb")
connection = connect(*db_params)
7. Функции с фиксированной структурой
Когда структура данных не меняется:
# Константные данные
DIRECTIONS = (
(0, 1, "North"),
(1, 0, "East"),
(0, -1, "South"),
(-1, 0, "West")
)
for dx, dy, name in DIRECTIONS:
print(f"Direction {name}: dx={dx}, dy={dy}")
# Конфигурация с гарантией неизменяемости
DB_CONFIG = ("localhost", 5432, "admin", "password")
# Гарантируем, что конфиг не будет случайно переписан
8. Именованные кортежи (namedtuple)
Когда нужна семантика с читаемостью:
from collections import namedtuple
# Определяем структуру
Point = namedtuple('Point', ['x', 'y', 'z'])
Color = namedtuple('Color', ['r', 'g', 'b'])
# Создание
p = Point(x=1, y=2, z=3)
color = Color(r=255, g=0, b=0)
# Доступ по имени (читаемо!)
print(p.x, p.y, p.z)
print(color.r, color.g, color.b)
# Всё ещё кортеж
print(p[0]) # 1
print(p == (1, 2, 3)) # True
# Практический пример
from collections import namedtuple
User = namedtuple('User', ['id', 'name', 'email'])
def get_user_by_id(user_id):
row = db.query(f"SELECT id, name, email FROM users WHERE id={user_id}")
return User(*row)
user = get_user_by_id(123)
print(f"User {user.name} ({user.email})")
9. TypedDict для типизации
Подобно namedtuple но с типами (Python 3.8+):
from typing import TypedDict
class UserDict(TypedDict):
id: int
name: str
email: str
def get_user() -> UserDict:
return {"id": 1, "name": "Alice", "email": "alice@example.com"}
10. Распаковка с игнорированием значений
# Берём только нужные значения
data = ("Alice", 30, "NYC", 5000)
name, age, *_ = data # Игнорируем остаток
first, *middle, last = data
print(first, last) # Alice 5000
# В функциях
def process(main_value, *ignored_values):
return main_value * 2
result = process(10, 20, 30, 40) # 20
11. Производительность
Кортежи немного быстрее списков:
import sys
my_list = [1, 2, 3, 4, 5]
my_tuple = (1, 2, 3, 4, 5)
print(sys.getsizeof(my_list)) # ~56 bytes
print(sys.getsizeof(my_tuple)) # ~40 bytes
# Кортежи также быстрее в создании и доступе
Резюме: Используй кортежи когда:
- Нужен ключ словаря (списки не подходят)
- Хочешь добавить в set (для уникальности)
- Возвращаешь из функции несколько значений
- Нужна гарантия неизменяемости данных
- Используешь в цикле for распаковкой
- Константные данные (конфиг, направления и т.д.)
- Нужна производительность (немного быстрее списков)
- Типизированные данные (namedtuple, TypedDict)
Кортежи и списки дополняют друг друга: списки для изменяемых данных, кортежи для неизменяемых и более интенсивно используемых.