← Назад к вопросам

Какие знаешь неизменяемые структуры данных в Python?

1.0 Junior🔥 181 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Неизменяемые структуры данных в Python

Неизменяемость (immutability) — это ключевая концепция в Python. За 10+ лет использую их в production коде регулярно.

tuple — кортеж

Кортеж — самая основная неизменяемая структура:

point = (1, 2, 3)
colors = ("red", "green", "blue")
single = (42,)  # Не забыть запятую для одного элемента!

# Доступ
print(point[0])  # 1
print(point[-1])  # 3

# Неизменяемость
point[0] = 5  # TypeError

# Распаковка
x, y, z = point

# Используй как ключи словаря
coord_to_distance = {(0, 0): 0, (1, 1): 1.414}

frozenset — неизменяемое множество

immutable_set = frozenset([1, 2, 3, 4, 5])
status = frozenset(["active", "inactive", "pending"])

# Операции множеств
set1 = frozenset([1, 2, 3])
set2 = frozenset([2, 3, 4])

print(set1 & set2)  # frozenset({2, 3})
print(set1 | set2)  # frozenset({1, 2, 3, 4})
print(set1 - set2)  # frozenset({1})

# Использование как ключ словаря
permissions = {
    frozenset(["read"]): "viewer",
    frozenset(["read", "write"]): "editor"
}

user_perms = frozenset(["read", "write"])
print(permissions[user_perms])  # editor

str — строка

Строки в Python неизменяемы:

text = "Hello"

# Любая операция возвращает новую строку
upper_text = text.upper()

# Попытка изменить
text[0] = "h"  # TypeError

# Конкатенация создаёт новую строку
greeting = "Hello" + " " + "World"

bytes — неизменяемые байты

data = b"Hello World"

# Доступ
print(data[0])  # 72
print(data[0:5])  # b'Hello'

# Неизменяемость
data[0] = ord("h")  # TypeError

# Для изменяемых байтов используй bytearray
mutable_data = bytearray(b"Hello")
mutable_data[0] = ord("h")
print(mutable_data)  # bytearray(b'hello')

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

from collections import namedtuple

Point = namedtuple("Point", ["x", "y"])
User = namedtuple("User", ["id", "name", "email"])

p = Point(x=1, y=2)
print(p.x, p.y)  # 1 2
print(p[0])  # 1

user = User(id=1, name="Alice", email="alice@example.com")
print(user.name)  # Alice

# Неизменяемость
p.x = 5  # AttributeError

# Создать новый с помощью _replace
p_new = p._replace(x=5)
print(p_new)  # Point(x=5, y=2)

# Удобно для документации
def calculate_distance(p1: Point, p2: Point) -> float:
    return ((p2.x - p1.x)**2 + (p2.y - p1.y)**2)**0.5

Типизированные именованные кортежи (NamedTuple)

from typing import NamedTuple

class Config(NamedTuple):
    host: str
    port: int
    debug: bool = False
    timeout: int = 30

config = Config(host="localhost", port=8000, debug=True)
print(config.host)  # localhost

Dataclass с frozen=True

from dataclasses import dataclass, replace

@dataclass(frozen=True)
class Person:
    name: str
    age: int
    email: str

person = Person(name="John", age=30, email="john@example.com")

# Неизменяемость
person.age = 31  # FrozenInstanceError

# Используй как ключ словаря
people_ages = {person: 30}

# Создай модифицированную копию
person_updated = replace(person, age=31)
print(person_updated)  # Person(name='John', age=31, email='john@example.com')

Почему неизменяемость важна

# Проблема с изменяемыми структурами
config = {"host": "localhost", "port": 8000}

def setup_server(settings):
    settings["host"] = "0.0.0.0"  # Изменили оригинал!
    return settings

setup_server(config)
print(config)  # Испорчено!

# Решение: неизменяемые структуры
Config = namedtuple("Config", ["host", "port"])
config = Config(host="localhost", port=8000)

def setup_server(settings: Config) -> Config:
    # Обязаны создать новый объект
    return Config(host="0.0.0.0", port=settings.port)

config = setup_server(config)
print(config)  # Оригинал не повреждён!

Практические рекомендации

  1. API контракты: используй namedtuple или dataclass(frozen=True) для функций
  2. Конфигурация: неизменяемость гарантирует что конфиг не сломается
  3. Dictionary keys: только неизменяемые типы (tuple, frozenset, str)
  4. Threading: неизменяемые объекты безопаснее в многопоточности
  5. Caching: неизменяемые значения можно кешировать

Неизменяемые структуры — это не прихоть функционального программирования, а реальная защита от ошибок в production коде.

Какие знаешь неизменяемые структуры данных в Python? | PrepBro