Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
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
- Любые сложные структуры: комбинация всего выше
Единого ограничения нет — словарь держит ссылку на объект, а не копию.