← Назад к вопросам
Является ли изменяемым объектом словарь?
2.2 Middle🔥 141 комментариев
#DevOps и инфраструктура#Django
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Является ли изменяемым объектом словарь?
Да, словарь (dict) — это изменяемый (mutable) объект.
Что такое изменяемость
Изменяемый объект (Mutable) — объект, содержимое которого можно изменять после создания, без создания нового объекта.
Неизменяемый объект (Immutable) — объект, который нельзя изменять. Любое "изменение" создаёт новый объект.
Словарь — изменяемый объект
Словарь можно изменять после создания несколькими способами:
1. Добавление и изменение элементов
# Создаём словарь
my_dict = {"name": "Иван", "age": 25}
print(f"ID словаря: {id(my_dict)}")
# Добавляем новый ключ
my_dict["city"] = "Москва"
print(f"ID словаря после добавления: {id(my_dict)}") # ОДИН И ТОТ ЖЕ ID!
# Изменяем существующее значение
my_dict["age"] = 26
print(f"ID словаря после изменения: {id(my_dict)}") # ОДИН И ТОТ ЖЕ ID!
print(my_dict) # {'name': 'Иван', 'age': 26, 'city': 'Москва'}
Обратите внимание: ID словаря не меняется! Мы изменяем содержимое существующего объекта, а не создаём новый.
2. Удаление элементов
my_dict = {"a": 1, "b": 2, "c": 3}
original_id = id(my_dict)
# Удаляем ключ
del my_dict["b"]
print(f"ID после удаления: {id(my_dict)}") # ОДИН И ТОТ ЖЕ!
# Используем pop()
value = my_dict.pop("c")
print(f"ID после pop: {id(my_dict)}") # ОДИН И ТОТ ЖЕ!
print(my_dict) # {'a': 1}
3. Методы изменения словаря
my_dict = {"x": 10, "y": 20}
original_id = id(my_dict)
# update() — добавляет/обновляет элементы
my_dict.update({"z": 30, "x": 100})
print(f"ID после update: {id(my_dict)}") # ОДИН И ТОТ ЖЕ!
print(my_dict) # {'x': 100, 'y': 20, 'z': 30}
# clear() — удаляет все элементы
my_dict.clear()
print(f"ID после clear: {id(my_dict)}") # ОДИН И ТОТ ЖЕ!
print(my_dict) # {}
Сравнение с неизменяемыми объектами
Строка (immutable)
# Создаём строку
my_str = "Hello"
original_id = id(my_str)
print(f"ID строки: {original_id}")
# Пытаемся "изменить"
my_str = my_str + " World"
print(f"ID после конкатенации: {id(my_str)}") # ДРУГОЙ ID!
# Python создал новую строку, а не изменил существующую
print(f"ID изменился: {original_id != id(my_str)}") # True
Кортеж (immutable)
my_tuple = (1, 2, 3)
original_id = id(my_tuple)
# Пытаемся изменить элемент
try:
my_tuple[0] = 100 # TypeError!
except TypeError as e:
print(f"Ошибка: {e}")
# "Добавление" элемента создаёт новый кортеж
my_tuple = my_tuple + (4,)
print(f"ID кортежа изменился: {id(my_tuple) != original_id}") # True
Практические следствия
Проблема: передача словаря в функцию
def modify_dict(d):
d["modified"] = True
# Создаём словарь
original = {"name": "Test"}
modify_dict(original)
# ИЗМЕНИЛСЯ!
print(original) # {'name': 'Test', 'modified': True}
Почему? Потому что словарь изменяемый. Функция получает ссылку на тот же объект и может его менять.
Для защиты используйте копию:
import copy
def modify_dict(d):
d["modified"] = True
original = {"name": "Test"}
modify_dict(copy.copy(original)) # Или copy.deepcopy()
# НЕ ИЗМЕНИЛСЯ!
print(original) # {'name': 'Test'}
Проблема: использование словаря как ключа
# Списки (mutable) нельзя использовать как ключи
try:
my_dict = {[1, 2]: "value"} # TypeError!
except TypeError as e:
print(f"Ошибка: {e}")
# Словари (mutable) тоже нельзя
try:
my_dict = {{"a": 1}: "value"} # TypeError!
except TypeError as e:
print(f"Ошибка: {e}")
# Только неизменяемые объекты
my_dict = {
(1, 2): "кортеж", # OK
"string": "строка", # OK
42: "число", # OK
frozenset([1, 2]): "frozenset" # OK
}
print(my_dict)
Проблема: использование мутабельных значений
# Создаём словарь со списком (mutable)
data = {"items": [1, 2, 3]}
# Копируем ссылку
copy1 = data
data["items"].append(4)
print(copy1) # {'items': [1, 2, 3, 4]} — ИЗМЕНИЛСЯ!
# Правильная глубокая копия
import copy
copy2 = copy.deepcopy(data)
data["items"].append(5)
print(copy2) # {'items': [1, 2, 3, 4]} — НЕ ИЗМЕНИЛСЯ!
Таблица изменяемости объектов Python
Изменяемые (Mutable):
- dict (словарь)
- list (список)
- set (множество)
- bytearray
Неизменяемые (Immutable):
- str (строка)
- tuple (кортеж)
- int, float, complex
- frozenset
- bytes
- None, True, False
Проверка изменяемости
# Python не имеет встроенного способа проверить изменяемость
# Но можно проверить хешируемость (unhashable = mutable)
def is_hashable(obj):
try:
hash(obj)
return True
except TypeError:
return False
print(f"Словарь хешируемый? {is_hashable({})}") # False (не хешируемый)
print(f"Кортеж хешируемый? {is_hashable(())}") # True (хешируемый)
print(f"Список хешируемый? {is_hashable([])}") # False (не хешируемый)
Практическая рекомендация
Так как словари изменяемые:
- Будьте осторожны при передаче в функции — функции могут изменить словарь
- Используйте копии для защиты исходных данных
- Не используйте словари как ключи — это вызовет ошибку
- Помните о side effects — изменение элементов внутри словаря может иметь неожиданные последствия
Резюме
Да, словарь — мутабельный объект. Это означает:
- Можно добавлять, удалять, изменять элементы
- ID словаря не меняется при модификации
- Функции, получившие словарь, могут его изменить
- Словари нельзя использовать как ключи других словарей