<MyRusakov.ru />

WordPress 6 с Нуля до Гуру

WordPress 6 с Нуля до Гуру

Этот курс научит Вас созданию самых разных сайтов на самой популярной в мире CMS - WordPress. Вы увидите установку и настройку локального сервера, разбор каждой настройки, каждой кнопки и каждого пункта меню в панели WordPress.

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

Помимо уроков к курсу идут упражнения для закрепления материала.

И, наконец, к курсу идёт ценнейший Бонус по тому, как используя ChatGPT и создавая контент для сайта, можно выйти на пассивный доход. Вы наглядно увидите, как зарегистрироваться в ChatGPT (в том числе, и если Вы из России), как правильно выбрать тему для сайта, как правильно генерировать статьи для него(чтобы они индексировались поисковыми системами) и как правильно монетизировать трафик на сайте.

Подробнее
Подписка

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

YouTube Подписаться

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Какая тема Вас интересует больше?

copy vs deepcopy в Python: поверхностное и глубокое копирование простыми словами

copy vs deepcopy в Python: поверхностное и глубокое копирование простыми словами

Одна из самых частых ошибок новичков в Python — непреднамеренное изменение исходных данных при работе с «копиями». Ключ к решению — понимать разницу между поверхностным копированием (shallow copy) и глубоким копированием (deep copy), а также правильно выбирать инструмент: срезы, методы коллекций, конструкторы или модуль copy.

Быстрое напоминание: присваивание — это не копирование

a = [1, [2, 3]]
b = a  # просто новая ссылка на тот же объект
b[1].append(4)
print(a)  # [1, [2, 3, 4]] — изменился и a, и b

Оператор = лишь создаёт ещё одну ссылку на тот же объект. Чтобы получить независимые данные, нужен именно копирующий приём.

Поверхностное копирование (shallow copy): когда достаточно

Shallow copy копирует контейнер верхнего уровня, но вложенные объекты продолжают ссылаться на те же экземпляры. Это быстро и достаточно, если структура не вложенная или вы уверены, что вложенные элементы неизменяемы (числа, строки, кортежи без изменяемых полей и т.п.).

Способы сделать поверхностную копию

  • Списки: lst[:], list(lst), lst.copy()
  • Словари: dict(d), d.copy(), {**d}
  • Множества: set(s), s.copy()
  • Универсально: copy.copy(obj)
import copy

lst = [1, 2, 3]
lst_copy = lst[:]            # или list(lst), или lst.copy()

d = {"a": 1, "b": 2}
d_copy = d.copy()            # или dict(d), или {**d}

s = {1, 2, 3}
s_copy = s.copy()            # или set(s)

# Универсально
x_copy = copy.copy(lst)

Где shallow copy ломается

import copy

a = [1, [2, 3]]
b = copy.copy(a)     # поверхностная копия
b[1].append(4)
print(a)  # [1, [2, 3, 4]] — вложенный список общий!

Вывод: если у вас есть вложенные изменяемые объекты (списки, словари, множества, пользовательские объекты с изменяемыми полями) — поверхностного копирования недостаточно.

Глубокое копирование (deep copy): когда нужно

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

import copy

a = [1, [2, 3]]
c = copy.deepcopy(a)
c[1].append(4)
print(a)  # [1, [2, 3]] — оригинал не изменился
print(c)  # [1, [2, 3, 4]]

Deepcopy — «тормознее» и «дороже» по памяти, зато гарантирует изоляцию данных. Используйте его, когда структура сложная и вы точно не хотите побочных эффектов.

Модуль copy: copy() и deepcopy() на практике

import copy

# Вложенные словари и списки
profile = {
    "name": "Ann",
    "tags": ["new"],
    "prefs": {"theme": "dark"}
}

shallow = copy.copy(profile)      # или profile.copy()
shallow["tags"].append("vip")
print(profile["tags"])  # ['new', 'vip'] — изменился оригинал

deep = copy.deepcopy(profile)
deep["prefs"]["theme"] = "light"
print(profile["prefs"]["theme"])  # 'dark' — оригинал не тронут

Копирование списка словарей (частый кейс)

rows = [
    {"id": 1, "tags": ["a"]},
    {"id": 2, "tags": ["b"]},
]

# Вариант 1: глубокая копия всей структуры
import copy
rows_deep = copy.deepcopy(rows)

# Вариант 2: «контролируемое» копирование (быстрее, если структура известна)
rows_safe = [{**r, "tags": r["tags"][:]} for r in rows]

rows_safe[0]["tags"].append("x")
print(rows[0]["tags"])  # ['a'] — оригинал не изменился

Равенство и идентичность: как проверить, что мы действительно скопировали

import copy

a = [1, [2]]
b = copy.copy(a)
c = copy.deepcopy(a)

print(a == b == c)  # True — содержимое одинаковое
print(a is b)       # False — разные объекты верхнего уровня
print(a[1] is b[1]) # True  — shallow copy: вложенный список общий
print(a[1] is c[1]) # False — deep copy: вложенный список скопирован

Производительность: не копируйте «просто так»

Глубокое копирование — операция дорогая. Если можно создать объект «с нуля» — часто это быстрее и экономичнее. Для больших данных оценивайте стоимость через timeit.

from timeit import timeit
setup = """
import copy
data = [{"i": i, "lst": list(range(100))} for i in range(1000)]
"""
print("shallow:", timeit("copy.copy(data)", setup=setup, number=100))
print("deep:   ", timeit("copy.deepcopy(data)", setup=setup, number=100))

Советы по скорости:

  • Копируйте только то, что нужно (избирательно, как в примере с rows_safe).
  • Избегайте deepcopy в горячих участках кода без необходимости.
  • Не копируйте неизменяемые объекты — это бессмысленно (строки, числа, кортежи без вложенных изменяемых полей).

Подводные камни и тонкости

  • Кортежи неизменяемы, но если внутри них есть изменяемые объекты, shallow copy сохранит общие ссылки на них.
  • deepcopy обходится с циклическими ссылками с помощью memo-таблицы, поэтому не зациклится, но может быть дорогим по времени и памяти.
  • Библиотеки могут иметь свои правила копирования. Например, в NumPy a.view() — это не копия, а a.copy() — реальная копия буфера.
  • Для pandas используйте df.copy(deep=True) для гарантированного отделения данных.

Мини-пример с пользовательским классом

import copy
from dataclasses import dataclass

@dataclass
class Point:
    x: int
    meta: dict

p1 = Point(10, {"tags": ["a"]})
p2 = copy.copy(p1)       # meta общая ссылка
p3 = copy.deepcopy(p1)   # всё независимое

p2.meta["tags"].append("b")
print(p1.meta["tags"])  # ['a', 'b'] — shallow копия

p3.meta["tags"].append("c")
print(p1.meta["tags"])  # ['a', 'b'] — deep копия не тронула оригинал

Чек-лист: copy vs deepcopy в Python

  • У меня вложенные изменяемые объекты? Да → рассмотрите deepcopy; Нет → достаточно shallow.
  • Нужна максимальная скорость? Копируйте выборочно, избегайте deepcopy без повода.
  • Копирую список словарей? Используйте list comprehension + dict.copy() и копирование вложенных коллекций по месту.
  • Работаю с внешними библиотеками (NumPy, pandas)? Ищите их «правильный» способ копирования данных.

Заключение

Поверхностное и глубокое копирование — базовый навык, который спасает от трудноуловимых багов в Python. Разбирайтесь в структуре ваших данных, выбирайте правильный инструмент и держите в уме компромисс между скоростью и безопасностью. Хотите системно укрепить базу и быстро расти в уровне? Рекомендую посмотреть программу и начать обучение по курсу «Программирование на Python с Нуля до Гуру» — стартуйте уверенно и без пробелов.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (https://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: https://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: https://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

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

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.