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

Note

В Python типы данных можно разделить на две категории: изменяемые и неизменяемые. Понимание разницы между ними критически важно, поскольку это влияет на то, как данные ведут себя при передаче в функции или при их изменении.

Содержание:

  1. Неизменяемые типы данных
  2. Изменяемые типы данных
  3. Главное об Изменяемых и Неизменяемых типах данных
  4. Как работает память в Python
  5. Практика

Теория

Базовые типы мы разбирали в 02.02 - Переменные и Типы данных, а коллекции — в 02.04 - Коллекции данных. Теперь посмотрим, как они ведут себя при изменении.

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

Note

В Python неизменяемые (immutable) типы данных — это такие объекты, которые нельзя изменить после их создания. Если вы пытаетесь изменить их, создаётся новый объект, а переменная начинает ссылаться на него.

Основные неизменяемые типы данных

  • Целые числа (int)

    • Числа в Python неизменяемы. Если вы выполняете операцию с числом, создаётся новый объект.

    Пример:

    a = 10
    b = a + 5  # Создаётся новый объект, a остаётся равным 10
    print(a)  # 10
    print(b)  # 15
  • Вещественные числа (float)

    • Как и целые числа, вещественные числа неизменяемы.

    Пример:

    pi = 3.14
    new_pi = pi + 0.001
    print(pi)       # 3.14
    print(new_pi)   # 3.141
  • Кортежи (tuple)

    • Кортежи — неизменяемые последовательности. Элементы кортежа нельзя изменить после его создания.

    Пример:

    fruits = ("apple", "banana", "cherry")
    # fruits[0] = "orange"  # Ошибка! Кортеж неизменяем
    print(fruits)  # ('apple', 'banana', 'cherry')
  • Строки (str)

    • Строки в Python также неизменяемы. Любые операции со строками создают новую строку.

    Пример:

    text = "Hello"
    new_text = text + " World"
    print(text)      # "Hello"
    print(new_text)  # "Hello World"
  • Логические значения (bool)

    • Значения True и False тоже неизменяемы.

    Пример:

    flag = True
    another_flag = not flag
    print(flag)          # True
    print(another_flag)  # False

Почему неизменяемость важна?

Tip

  1. Оптимизация памяти:

    Неизменяемые объекты занимают меньше памяти, так как могут быть переиспользованы.

    Пример: Если два числа a = 10 и b = 10, Python хранит их в одной области памяти.

  2. Безопасность:

    Неизменяемые типы данных защищены от непреднамеренных изменений, что снижает вероятность ошибок.

  3. Хэшируемость:

    Из-за неизменяемости объекты таких типов можно использовать в качестве ключей в словарях (dict) или в множествах (set).


Пример практики

Example

В папке Data types → В папке immutable создайте файл immutable_examples.py.

Задания:

  • Работа с числами:

    Создайте переменную a со значением 10. Создайте ещё одну переменную b, присвоив ей результат a + 5. Проверьте, изменилось ли значение переменной a.

  • Кортежи:

    Создайте кортеж с именем colors, содержащий три цвета. Попробуйте изменить один из элементов кортежа. Что произойдёт?

  • Строки:

    Создайте строку text со значением "Python". Добавьте к ней " Rocks!". Проверьте, изменилась ли исходная строка.

  • Хэшируемость:

    Создайте словарь с ключами типа int, float, str, и tuple. Попробуйте использовать в качестве ключа список. Объясните, почему это вызывает ошибку.


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

Note

Описание:

Изменяемые (mutable) типы данных позволяют изменять содержимое объекта после его создания. При этом переменная продолжает ссылаться на тот же объект, а его идентификатор (адрес в памяти) остаётся неизменным.

Основные изменяемые типы данных

  • Списки (list)

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

    Пример:

    fruits = ["apple", "banana", "cherry"]
    print(id(fruits))  # Идентификатор объекта
     
    fruits.append("orange")
    print(fruits)      # ['apple', 'banana', 'cherry', 'orange']
    print(id(fruits))  # Идентификатор остался тем же
  • Множества (set)

    • Множества — это неупорядоченные коллекции уникальных элементов. Вы можете добавлять и удалять элементы.

    Пример:

     
    numbers = {1, 2, 3}
    print(id(numbers))  # Идентификатор объекта
     
    numbers.add(4)
    print(numbers)      # {1, 2, 3, 4}
    print(id(numbers))  # Идентификатор остался тем же
  • Словари (dict)

    • Словари содержат пары ключ-значение, которые можно добавлять, изменять или удалять.

    Пример:

    user = {"name": "Alice", "age": 25}
    print(id(user))  # Идентификатор объекта
     
    user["location"] = "New York"
    print(user)      # {'name': 'Alice', 'age': 25, 'location': 'New York'}
    print(id(user))  # Идентификатор остался тем же

Почему изменяемость важна?

Tip

  1. Эффективность работы с данными:

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

  2. Функциональные возможности:

    Изменяемые объекты предоставляют гибкость для работы с коллекциями данных, которые требуют динамического изменения.

  3. Использование в сложных структурах данных:

    Списки, словари и множества широко используются для создания сложных структур, таких как графы, хеш-таблицы и т.д.

Практическое задание

Example

В папке Data types → В папке mutable создайте файл mutable_examples.py.

Задания:

  • Списки:

    Создайте список colors с элементами "red", "green", и "blue". Добавьте в этот список "yellow", а затем удалите "green". Проверьте идентификатор списка до и после изменений.

  • Множества:

    Создайте множество numbers с числами 1, 2, 3. Добавьте в это множество 4 и удалите 1. Проверьте, как изменилось содержимое множества.

  • Словари:

    Создайте словарь person с ключами "name" и "age". Добавьте новый ключ "job" со значением "developer". Затем измените значение "age" на 30. Проверьте, остаётся ли идентификатор словаря неизменным.

  • Сравнение с неизменяемыми типами:

    Создайте список и кортеж с одинаковыми элементами. Попробуйте изменить содержимое каждого из них. Объясните, почему список изменяется, а кортеж — нет.


Главное об Изменяемых и Неизменяемых типах данных

  • Общая инфа по типам данных в питоне, типы последовательностей+ таблица

    | | Изменение ❌=Изменять нельзя, только создаются новые объекты в памяти; ✅ = изменять можно, ссылка на объект в памяти та же | Порядок ❌=Порядок элементов не важен; ✅=Порядок элементов имеет значение | Одинаковые элементы❌=Не допускаются одинаковые элементы; ✅= допускаются одинаковые элементы | | --- | --- | --- | --- | | list | ✅ | ✅ | ✅ | | tuple | ❌ | ✅ | ✅ | | set | ✅ | ❌ | ❌ | | range | ❌ | ✅ | ❌ | | dict | ✅ | ❌ | ❌ | | str | ❌ | ✅ | ✅ |

    ✅ , ❌

    Если вы хотите создавать последовательность уникальный элементов, то лучше всего подойдет набор “set”

    Если необходимо хранить большие объемы данных у которых есть идентификаторы ключ, то подходит лучше всего словарь dict

    Если необходимо последовательность с разными типами и повторений, то лучше выбрать список list

    Если необходим набор данных который нельзя будет удалять или изменять, то лучше всего подходит Кортеж tuple

    Если необходим просто выполнить необходимое число действий например N раз или 100 раз, то тогда нам подходит диапазон range

    Для создание коротких, или длиных строк str

Tip

Запомните слово LSD - 🤪 Можно изменять только три типа данных LSD - LIST(список), SET(набор или множество), DICT(словарь)


Как работает память в Python

Note

Когда вы создаёте объект в Python, ему выделяется уникальный адрес в памяти. Этот адрес можно увидеть с помощью функции id(). Для неизменяемых типов данных, таких как строки, целые числа и кортежи, адрес объекта в памяти остаётся неизменным, даже если вы “изменяете” значение переменной — на самом деле создаётся новый объект.

Адрес памяти в Python

Note

В Python каждая переменная ссылается на объект в памяти. У каждого объекта есть уникальный идентификатор, который можно получить с помощью функции id().

Что такое адрес памяти?

  • id() возвращает адрес памяти, где хранится объект.
  • Этот адрес уникален для каждого объекта в процессе выполнения программы.
  • Для неизменяемых объектов (например, чисел, строк, кортежей) адрес может измениться, если вы «изменяете» значение переменной, так как создаётся новый объект.
  • Для изменяемых объектов (например, списков, словарей) адрес памяти остаётся постоянным, пока объект существует.

Пример: Адрес памяти для неизменяемых объектов

# Неизменяемый объект: число
num = 10
print("Число:", num)
print("Адрес памяти:", id(num))  # Например: 140724564123456
 
# Изменяем значение переменной
num = num + 5
print("Новое значение числа:", num)
print("Адрес памяти:", id(num))  # Например: 140724564654321 (изменился)

Пример: Адрес памяти для изменяемых объектов

# Изменяемый объект: список
my_list = [1, 2, 3]
print("Список:", my_list)
print("Адрес памяти:", id(my_list))  # Например: 140724564987654
 
# Изменяем содержимое списка
my_list.append(4)
print("Список после изменения:", my_list)
print("Адрес памяти:", id(my_list))  # Например: 140724564987654 (осталсятемже )

Итог:

  • Неизменяемые объекты: При “изменении” создаётся новый объект, и адрес памяти изменяется.
  • Изменяемые объекты: При изменении содержимого адрес памяти остаётся тем же.

Какие инструменты помогают ему очищать память

Note

В Python за управление памятью отвечает сборщик мусора (Garbage Collector, GC). Этот механизм автоматически отслеживает объекты, которые больше не используются, и освобождает их память.

Note

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


Практика 🧪

Example

  1. Сделать конспект в миро

⬅️ Назад: 02.04 - Коллекции данных | Далее: 02.06 - If else ➡️ Модуль: 02 - MOC