Вопрос с собеседования · Python

Чем изменяемые типы отличаются от неизменяемых?

JuniorТипы данных
Ещё спрашивают так:
  • Какие типы в Python изменяемые, а какие нет?
  • Что такое mutable и immutable объекты?
Коротко

Изменяемый объект меняется на месте, неизменяемый — только заменяется новым.

  • Неизменяемые: int, float, str, tuple, frozenset, bytes, bool, None
  • Изменяемые: list, dict, set, bytearray, обычные объекты классов

А ещё Скажите про хешируемость: ключом словаря может быть только неизменяемое

Подробно

В Python переменная — это имя, привязанное к объекту. Разница в том, что можно сделать с самим объектом.

У изменяемого объекта (list, dict, set) можно поменять содержимое, и все имена, которые на него ссылаются, увидят изменение: a = [1]; b = a; b.append(2) — теперь и a == [1, 2].

Неизменяемый объект (int, str, tuple) поменять нельзя. Операция, которая выглядит как изменение, создаёт новый объект и перепривязывает имя: после s = "ab"; s += "c" имя s указывает на другую строку, а старая не изменилась. Это видно по id() до и после.

Следствия, о которых обычно спрашивают:

  • Хешируемость. Ключи dict и элементы set должны быть хешируемыми, а хеш не должен меняться за время жизни объекта. Поэтому список ключом быть не может, а кортеж из неизменяемых элементов — может.
  • Кортеж со списком внутри. Сам кортеж неизменяем (нельзя заменить элемент), но список внутри можно менять — и такой кортеж уже не хешируется.
  • Передача в функцию. Функция получает ссылку на тот же объект: изменяемый аргумент она может поменять «снаружи», неизменяемый — нет.

Пример

a = [1, 2]
b = a
b.append(3)
print(a)          # [1, 2, 3] — один и тот же список

s = "py"
t = s
t += "thon"
print(s, t)       # py python — у t теперь новая строка

hash((1, 2))      # работает
hash((1, [2]))    # TypeError: unhashable type: 'list'

Что хотят услышать

  • Разница сформулирована через объект, а не через переменную: имя перепривязывается, объект меняется или нет.
  • Названы типы с обеих сторон, включая tuple, str, frozenset.
  • Связь с хешируемостью и ключами словаря.
  • Понимание, что кортеж со списком внутри «частично изменяем» и не хешируется.

Частые ошибки

  • «Строку можно изменить через +=» — нет, создаётся новая строка.
  • «Кортеж полностью неизменяем» без оговорки про изменяемые элементы внутри.
  • Путать изменяемость объекта с возможностью переприсвоить переменную.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗str изменяем, его можно поменять на месте
  • ✗tuple становится изменяемым, если в нём лежат только числа
  • ✓Неизменяемые — int, str, tuple, frozenset; изменяемые — list, dict, set
  • ✗Ключом словаря может быть любой изменяемый объект

Что спросят дальше

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования