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

Является ли изменяемым объектом словарь?

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 (не хешируемый)

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

Так как словари изменяемые:

  1. Будьте осторожны при передаче в функции — функции могут изменить словарь
  2. Используйте копии для защиты исходных данных
  3. Не используйте словари как ключи — это вызовет ошибку
  4. Помните о side effects — изменение элементов внутри словаря может иметь неожиданные последствия

Резюме

Да, словарь — мутабельный объект. Это означает:

  • Можно добавлять, удалять, изменять элементы
  • ID словаря не меняется при модификации
  • Функции, получившие словарь, могут его изменить
  • Словари нельзя использовать как ключи других словарей
Является ли изменяемым объектом словарь? | PrepBro