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

Что может храниться в словаре?

1.3 Junior🔥 31 комментариев
#Другое

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

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

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

Python словарь (Dictionary): что может храниться

Словарь — это мощная и гибкая структура данных в Python. Может содержать практически что угодно.

Основные типы значений

1. Примитивные типы

# Строки, числа, булевы значения
data = {
    "name": "John",          # str
    "age": 30,               # int
    "salary": 50000.50,      # float
    "is_active": True,       # bool
    "nothing": None          # NoneType
}

print(data["name"])   # 'John'
print(data["age"])    # 30
print(data["is_active"])  # True

2. Коллекции

# Список, кортеж, множество
data = {
    "tags": ["python", "django", "rest"],  # list
    "coordinates": (10.5, 20.3),            # tuple
    "unique_ids": {1, 2, 3, 4},             # set
    "permissions": frozenset(['read', 'write'])  # frozenset (immutable)
}

print(data["tags"][0])         # 'python'
print(data["coordinates"][1])  # 20.3

3. Вложенные словари

Словарь может содержать другие словари:

# Вложенные структуры
user = {
    "id": 1,
    "name": "John",
    "address": {
        "street": "Main St",
        "city": "NYC",
        "coordinates": {
            "lat": 40.7128,
            "lon": -74.0060
        }
    },
    "contacts": {
        "email": "john@example.com",
        "phone": "+1234567890"
    }
}

print(user["address"]["city"])  # 'NYC'
print(user["address"]["coordinates"]["lat"])  # 40.7128

4. Функции и лямбда

Словарь может содержать функции как значения:

def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

calculator = {
    "add": add,
    "subtract": subtract,
    "multiply": lambda x, y: x * y,
    "divide": lambda x, y: x / y if y != 0 else None
}

print(calculator["add"](5, 3))          # 8
print(calculator["multiply"](4, 2))     # 8

# Итерация по функциям
for operation, func in calculator.items():
    result = func(10, 5)
    print(f"{operation}: {result}")

5. Объекты и экземпляры классов

class User:
    def __init__(self, name, email):
        self.name = name
        self.email = email
    
    def __repr__(self):
        return f"User({self.name}, {self.email})"

users_db = {
    "user1": User("John", "john@example.com"),
    "user2": User("Jane", "jane@example.com"),
    "admin": User("Admin", "admin@example.com")
}

print(users_db["user1"].email)  # 'john@example.com'

# Итерация
for user_id, user in users_db.items():
    print(f"{user_id}: {user.name}")

6. Байты и бинарные данные

import hashlib

data = {
    "raw_bytes": b"hello world",
    "image_data": b"\x89PNG\r\n\x1a\n...",
    "hash": hashlib.sha256(b"password").digest(),
    "base64": b"aGVsbG8gd29ybGQ="
}

print(data["raw_bytes"])  # b'hello world'

7. Объекты datetime

from datetime import datetime, timedelta

events = {
    "created_at": datetime(2024, 3, 23, 10, 30),
    "updated_at": datetime.now(),
    "expires_at": datetime.now() + timedelta(days=7),
    "duration": timedelta(hours=2)
}

print(events["created_at"].strftime("%Y-%m-%d"))  # '2024-03-23'

8. Custom объекты и dataclass

from dataclasses import dataclass
from enum import Enum

class Status(Enum):
    PENDING = 1
    ACTIVE = 2
    COMPLETED = 3

@dataclass
class Task:
    id: int
    title: str
    status: Status
    priority: int

tasks = {
    "task1": Task(1, "Fix bug", Status.ACTIVE, 1),
    "task2": Task(2, "Add feature", Status.PENDING, 2),
    "task3": Task(3, "Write docs", Status.COMPLETED, 3)
}

for key, task in tasks.items():
    print(f"{key}: {task.title} ({task.status.name})")

9. Генераторы и итераторы

def number_generator():
    for i in range(10):
        yield i

callables = {
    "gen": number_generator(),
    "iter": iter([1, 2, 3, 4, 5]),
    "range": range(10)
}

print(next(callables["gen"]))  # 0
print(next(callables["gen"]))  # 1

Ограничения и правила

Что МОЖЕТ быть ключом

# Ключи должны быть hashable (неизменяемыми)
good_dict = {
    "name": "John",         # str - OK
    1: "one",               # int - OK
    (1, 2): "tuple",        # tuple - OK
    frozenset([1, 2]): "fs" # frozenset - OK
}

# Что НЕ может быть ключом
bad_dict = {
    [1, 2]: "list",         # TypeError: unhashable type: 'list'
    {"a": 1}: "dict",       # TypeError: unhashable type: 'dict'
    {1, 2}: "set"           # TypeError: unhashable type: 'set'
}

Что может быть значением (без ограничений)

# Всё работает
any_value_dict = {
    "list": [1, 2, 3],
    "dict": {"nested": True},
    "set": {1, 2, 3},
    "function": print,
    "lambda": lambda x: x**2,
    "class": MyClass,
    "none": None
}

Практические примеры

1. Кэш функции (Memoization)

def fibonacci(n, cache={}):
    """
    Словарь как кэш для хранения вычисленных значений
    """
    if n in cache:
        return cache[n]
    
    if n <= 1:
        return n
    
    result = fibonacci(n-1, cache) + fibonacci(n-2, cache)
    cache[n] = result  # Сохраняем в кэш
    return result

print(fibonacci(100))  # Очень быстро благодаря кэшу

2. Dispatcher паттерн (Command Pattern)

class APIHandler:
    def __init__(self):
        self.handlers = {
            "user.create": self.create_user,
            "user.update": self.update_user,
            "user.delete": self.delete_user,
            "post.create": self.create_post,
            "post.delete": self.delete_post
        }
    
    def dispatch(self, action, data):
        handler = self.handlers.get(action)
        if handler:
            return handler(data)
        else:
            raise ValueError(f"Unknown action: {action}")
    
    def create_user(self, data):
        return {"status": "ok", "user_id": 1}
    
    def update_user(self, data):
        return {"status": "ok"}
    
    def delete_user(self, data):
        return {"status": "deleted"}
    
    def create_post(self, data):
        return {"status": "ok", "post_id": 1}
    
    def delete_post(self, data):
        return {"status": "deleted"}

handler = APIHandler()
result = handler.dispatch("user.create", {"name": "John"})
print(result)  # {'status': 'ok', 'user_id': 1}

3. Конфигурация и настройки

config = {
    "database": {
        "host": "localhost",
        "port": 5432,
        "name": "myapp",
        "pool_size": 10
    },
    "cache": {
        "backend": "redis",
        "timeout": 3600,
        "key_prefix": "app:"
    },
    "features": {
        "dark_mode": True,
        "beta": False,
        "max_upload_size": 10 * 1024 * 1024  # 10MB
    },
    "logging": {
        "level": "INFO",
        "handlers": ["console", "file"]
    }
}

db_host = config["database"]["host"]
logger_level = config["logging"]["level"]

Best Practices

1. Используй .get() для безопасного доступа

data = {"name": "John"}

# Плохо - KeyError если нет ключа
age = data["age"]  # KeyError!

# Хорошо - возвращает None или default
age = data.get("age")  # None
age = data.get("age", 0)  # 0

2. Структурируй иерархические данные

# Плохо - плоская структура, непонятно
data = {
    "user_id": 1,
    "user_name": "John",
    "user_email": "john@example.com",
    "address_street": "Main St"
}

# Хорошо - вложенные словари
data = {
    "user": {
        "id": 1,
        "name": "John",
        "email": "john@example.com"
    },
    "address": {
        "street": "Main St"
    }
}

3. Используй defaultdict для параметров

from collections import defaultdict

# Вместо проверки каждый раз
groups = defaultdict(list)  # Если ключа нет, создаст пустой list
groups["python"].append("django")
groups["python"].append("fastapi")
# Нет KeyError!

Итог

Словарь может хранить:

  • Примитивы: str, int, float, bool, None
  • Коллекции: list, tuple, set, frozenset
  • Объекты: экземпляры классов, dataclass
  • Функции: функции, лямбда, методы
  • Другие типы: datetime, bytes, enum
  • Любые сложные структуры: комбинация всего выше

Единого ограничения нет — словарь держит ссылку на объект, а не копию.