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

Какая альтернатива словарю?

1.7 Middle🔥 81 комментариев
#Python Core

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

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

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

Альтернативы словарю в Python

Словарь (dict) — основная структура для хранения пар ключ-значение, но в зависимости от задачи существуют альтернативы с разными преимуществами.

1. collections.defaultdict

Используется когда нужно избежать KeyError для отсутствующих ключей:

from collections import defaultdict

# Обычный dict
regular_dict = {}
regular_dict['key']  # KeyError!

# defaultdict с автоматическим значением
count_dict = defaultdict(int)
count_dict['apple'] += 1  # Работает, возвращает 0 как default
count_dict['apple'] += 1
print(count_dict)  # defaultdict(<class 'int'>, {'apple': 2})

# С list
from collections import defaultdict
groups = defaultdict(list)
groups['team1'].append('Alice')
groups['team1'].append('Bob')

2. collections.Counter

Специализирован для подсчета элементов:

from collections import Counter

# Подсчет символов
text = "hello world"
counter = Counter(text)
print(counter)  # Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ...})

# Топ-3 элемента
print(counter.most_common(3))  # [('l', 3), ('o', 2), (' ', 1)]

# Подсчет элементов списка
fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
fruit_count = Counter(fruits)
print(fruit_count)  # Counter({'apple': 3, 'banana': 2, 'orange': 1})

3. collections.OrderedDict

До Python 3.7 это был единственный способ гарантировать порядок ключей (теперь обычный dict упорядочен):

from collections import OrderedDict

# Используется редко, но может быть полезен для совместимости
ordered = OrderedDict([('first', 1), ('second', 2), ('third', 3)])
for key, value in ordered.items():
    print(key, value)  # Гарантированный порядок

4. collections.ChainMap

Объединяет несколько словарей:

from collections import ChainMap

defaults = {'color': 'red', 'size': 'medium'}
user_settings = {'color': 'blue'}

config = ChainMap(user_settings, defaults)
print(config['color'])   # 'blue' (из user_settings)
print(config['size'])    # 'medium' (из defaults)
print(dict(config))      # {'color': 'blue', 'size': 'medium'}

5. types.SimpleNamespace

Для доступа к значениям как атрибутам объекта:

from types import SimpleNamespace

# Вместо dict с доступом по ключам
data = SimpleNamespace(name='Alice', age=30, city='Moscow')
print(data.name)  # 'Alice'
print(data.age)   # 30

# Удобнее чем
data_dict = {'name': 'Alice', 'age': 30, 'city': 'Moscow'}
print(data_dict['name'])  # Менее красиво

6. dataclasses.dataclass

Для структурированных данных с типизацией:

from dataclasses import dataclass
from typing import Optional

@dataclass
class Person:
    name: str
    age: int
    city: str = 'Moscow'
    email: Optional[str] = None

person = Person('Alice', 30)
print(person.name)  # 'Alice'
print(person)       # Person(name='Alice', age=30, city='Moscow', email=None)

# Автоматически получаешь __repr__, __eq__, и другие методы

7. pydantic.BaseModel

Если нужна валидация данных:

from pydantic import BaseModel, field_validator

class User(BaseModel):
    name: str
    age: int
    email: str
    
    @field_validator('age')
    @classmethod
    def age_must_be_positive(cls, v):
        if v < 0:
            raise ValueError('Age must be positive')
        return v

user = User(name='Alice', age=30, email='alice@example.com')
print(user.model_dump())  # {'name': 'Alice', 'age': 30, 'email': 'alice@example.com'}

# Неправильные данные — ошибка
User(name='Bob', age=-5, email='bob@example.com')  # ValidationError

8. attrs (@attrs.define)

Легковесная альтернатива dataclass:

import attrs

@attrs.define
class Book:
    title: str
    author: str
    pages: int = 0

book = Book('Python Guide', 'Guido', 300)
print(book.title)  # 'Python Guide'
print(book == Book('Python Guide', 'Guido', 300))  # True

9. NamedTuple

Для неизменяемых структур с типизацией:

from typing import NamedTuple

class Point(NamedTuple):
    x: float
    y: float
    z: float = 0.0

p = Point(1.0, 2.0)
print(p.x, p.y)  # 1.0 2.0
print(len(p))    # 3, tuple свойства

# Неизменяем
p.x = 5  # TypeError: can't set attribute

10. Пользовательские классы

Для сложной логики:

class Config:
    def __init__(self, **kwargs):
        self._data = kwargs
    
    def __getitem__(self, key):
        return self._data[key]
    
    def __setitem__(self, key, value):
        self._data[key] = value
    
    def __repr__(self):
        return f'Config({self._data})'

config = Config(host='localhost', port=8000)
print(config['host'])  # 'localhost'

Сравнение и выбор

ВариантКогда использоватьПреимущества
dictОбщий случайВстроен, гибкий
defaultdictОтсутствующие ключиИзбегает KeyError
CounterПодсчет элементовУдобные методы
SimpleNamespaceДоступ как атрибутЛаконично
dataclassТипизированные данныеАвтокод, производительность
PydanticВалидация данныхПроверка при создании
NamedTupleНеизменяемые данныеТипизация, неизменяемость

Выбор зависит от задачи: для простых данных — dict, для структурированных — dataclass, для валидации — Pydantic.

Какая альтернатива словарю? | PrepBro