ProgramaciónIngeniero de Datos

Explique la diferencia entre shallow copy (copia superficial) y deep copy (copia profunda), así como el comportamiento de copy.copy y copy.deepcopy al copiar objetos complejos. Proporcione un ejemplo donde un malentendido condujo a un error.

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

Copia superficial (shallow copy) crea un nuevo objeto de nivel superior, pero los objetos anidados (elementos de listas, diccionarios anidados, etc.) comparten memoria con el original. Copia profunda (deep copy) copia recursivamente todos los niveles de objetos.

Se puede usar a través del módulo copy:

import copy original = [[1, 2], [3, 4]] shallow = copy.copy(original) deep = copy.deepcopy(original) shallow[0][0] = 99 # Cambia tanto original como shallow print(original) # [[99, 2], [3, 4]] # Ahora con deep original = [[1, 2], [3, 4]] deep = copy.deepcopy(original) deep[0][0] = 99 print(original) # [[1, 2], [3, 4]]

Características:

  • copy.copy(obj): solo copia la "envoltura"
  • copy.deepcopy(obj): copia recursiva completa
  • Algunos objetos (por ejemplo, archivos abiertos, sockets) no se copian con deep copy (excepción)

Pregunta engañosa.

¿Qué sucederá al copiar una tupla que contiene objetos mutables?

Respuesta con ejemplo:

tuple es inmutable, pero sus elementos pueden ser mutables (por ejemplo, una lista). Shallow copy y deep copy difieren:

import copy t = ([1, 2], [3, 4]) shallow = copy.copy(t) deep = copy.deepcopy(t) shallow[0][0] = 99 print(t) # ([99, 2], [3, 4]) # Al hacer deep copy: t = ([1, 2], [3, 4]) deep = copy.deepcopy(t) deep[0][0] = 88 print(t) # ([1, 2], [3, 4])

Ejemplos de errores reales debido a la falta de conocimiento sobre las sutilezas del tema


Historia

En una aplicación de procesamiento de documentos, los datos se almacenaban en una lista dentro de un diccionario. Al copiar objetos con copy.copy, los elementos anidados se modificaban accidentalmente al modificar el nuevo objeto. Como resultado, los datos originales se cambiaron en otras partes del sistema. ¡Se produjo corrupción de datos! Se resolvió cambiando a deepcopy.


Historia

En un proyecto de aprendizaje automático, al guardar los hiperparámetros de los modelos, se copiaba la lista de configuraciones mediante asignación estándar y shallow copy, después de lo cual diferentes experimentos cambiaban mutuamente sus parámetros. La fuente del error se encontró tras diagnosticar el comportamiento de la copia de listas anidadas mediante deepcopy.


Historia

En un software financiero, se aplicó accidentalmente deep copy a un objeto que incluye un archivo abierto (handle), lo que provocó TypeError: cannot pickle '_io.TextIOWrapper' object — porque copy.deepcopy utiliza pickle bajo el capó. Se resolvió mediante un manejo explícito de tales campos o a través de la llamada a shallow copy.