Найти в Дзене
Записки сисадмина

Python. Наглядно о типах данных.

Знаете, что общего у собеседования и свидания с девушкой? В большинстве своем, тебе приходится отвечать на одни и те же вопросы. Именно поэтому существуют люди, которые мастерски проходят собеседования на те позиции, до которых не дотягивают по уровню. Но сейчас не об этом. Вне зависимости от твоего уровня и позиции, на которую ты собеседуешься, если ты в навыках указал "Python", ты услышишь вопрос: «Какие типы данных существуют в python?», или «Сколько типов данных в python?». Многие начинают перечислять: числа, списки, строки и т.д. Правильный ответ: «Два - изменяемые и неизменяемые». Изменяемые типы - это списки (list), множества (set) и словари (dict). На этом все. Все остальные - неизменяемые. Почему именно так? Все дело в принципах создания объектов и выделения памяти для них в python. Даже если вам кажется, что строка может изменяться, это не так. Я заранее предполагаю, что вы уже прошли стадии принятия Python, вам уже влили в уши про "коробочки с данными" и т.д. Наверно, вы уже
Оглавление

Знаете, что общего у собеседования и свидания с девушкой? В большинстве своем, тебе приходится отвечать на одни и те же вопросы. Именно поэтому существуют люди, которые мастерски проходят собеседования на те позиции, до которых не дотягивают по уровню.

Но сейчас не об этом. Вне зависимости от твоего уровня и позиции, на которую ты собеседуешься, если ты в навыках указал "Python", ты услышишь вопрос: «Какие типы данных существуют в python?», или «Сколько типов данных в python?».

Многие начинают перечислять: числа, списки, строки и т.д. Правильный ответ: «Два - изменяемые и неизменяемые».

Изменяемые типы - это списки (list), множества (set) и словари (dict). На этом все. Все остальные - неизменяемые.

Почему именно так? Все дело в принципах создания объектов и выделения памяти для них в python. Даже если вам кажется, что строка может изменяться, это не так.

Я заранее предполагаю, что вы уже прошли стадии принятия Python, вам уже влили в уши про "коробочки с данными" и т.д. Наверно, вы уже знаете, что в Python не существует тех самых каноничных "переменных", есть только ссылки на объекты. Если вы знакомы с Linux, воспринимайте переменные python как symlink'и. В общем, не будем задерживаться на этом. Немного погрузимся в мат. часть.

Разница в изменении переменных

  • Неизменяемые типы данных:

При создании переменной со строкой, python создаст объект в памяти и создаст на него ссылку из вашей переменной. Как только вы измените свою строку, python не будет ничего менять в предыдущем объекте. Он просто создаст новый и переместит ссылку на него, а старую строку из памяти удалит.

Увидеть это мы можем с помощью команды id(), которая покажет ID ячейки памяти нашего объекта.

-2

Мы видим, что ID объекта изменился, а значит - объект со старым ID был уже удален из памяти.

Важно понимать, что мы сейчас говорим именно про ID, а не про размер переменной.

  • Изменяемые типы данных:

Со списками, множествами и словарями python работает по-другому. Если с числом, или строкой заранее ясно, сколько они занимают памяти, то в список мы всегда можем добавить новый элемент. Давайте попробуем создать список и изменить его:

-3
-4

Мы видим, что значение нашей переменной изменилось, список увеличился на один элемент. Но его ID в памяти остался прежним.

Вывод: При попытке изменения "неизменяемых" типов данных, создается новый объект, а не меняется текущий.

Разница в сравнении переменных

В python существует два типа сравнения: по значениям (a == b) и по объектам (a is b). Второй тип ссылается на размер и на область памяти объекта, поэтому его можно назвать "строгим равенством". Давайте же посмотрим, как себя ведет python при создании нескольких переменных с одинаковым значением.

  • Неизменяемые типы данных:

Создадим две переменные с одинаковым числовым значением и проверим, будут ли эти переменные равны.

-5
-6

Мы видим 2 разных переменных, но с одинаковым ID. Это может означать только то, что они обе ссылаются на один и тот же объект в памяти.

Как это работает:

  1. Создается объект с числом "5" в памяти системы.
  2. Создается ссылка с переменной variable1 на этот объект.
  3. При создании variable2, python видит, что уже существует объект со значением "5" и не создает второй.
  4. Создается ссылка с переменной variable2 на тот же самый объект.

Если мы изменим одну из переменных, у второй поменяется ID? Нет.

-7
-8

При изменении первой переменной, ссылка со второй не будет затрагиваться.

  • Изменяемые типы данных:

Создадим два одинаковых списка и посмотрим, как они будут сравниваться между собой.

-9
-10

Тут все намного проще. Python изначально создал два разных списка. Проверку на равенство значений они проходят, так как элементы в них одинаковые, но вот ID у них разные. Почему?

Все просто: список может измениться в любой момент, при этом изменения не должны применяться также и к другому.

Разница в количестве выделяемой памяти

Посмотреть количество выделенной памяти под объект можно командой sys.getsizeof(). К сожалению, она не покажет, сколько места занимают вложенные элементы, но это нам сейчас не так критично.

Для наглядности, вот таблица выделения памяти под разные типы данных:

-11

Здесь мы можем заметить, что больше всего памяти выделяется под изменяемые типы данных.

Например, если мы создадим list и tuple с одинаковыми элементами внутри, на list выделится значительно больше памяти.

-12
-13

При увеличении размера списка и кортежа, разница занимаемой памяти между ними будет кратно увеличиваться.

Выводов никаких писать никакого смысла нет, ведь, если копнуть чуть глубже, мы поймем, что тип у всех данных в python устанавливается согласно логике работы системы. Хоть язык и высокоуровневый, по своей архитектуре он оптимизирован на то, чтобы не потреблять лишние ресурсы.