Explicación detallada de la asignación directa de Python, copia profunda y copia superficial

Declaración de derechos de autor: Este artículo es el artículo original del blogger y sigue el acuerdo de derechos de autor CC 4.0 BY-SA . Adjunte el enlace de la fuente original y esta declaración para reimprimir.
Enlace a este artículo: https://blog.csdn.net/zsq8187/article/details/109907066


Estoy aprendiendo Python. Pasé un día escribiendo una copia de las notas basada en mi propia revisión y prueba de comprensión. Después de pensarlo, publiquemos esta nota por separado)

Copia superficial y copia profunda

La asignación de objetos en Python se realiza directamente por referencia. Para copiar, debe utilizar el módulo de copia en la biblioteca estándar.

  • Asignación directa: pase la dirección de memoria directamente
  • Copia superficial copy.copy(): crea un nuevo objeto , copia las direcciones de memoria de todos los elementos dentro
  • Copia profunda copy.deepcopy(): cree un nuevo objeto , copie la dirección de memoria de forma inmutable y recursivamente cree un nuevo objeto y copie el contenido si contiene una variable (consulte el tipo de tupla a continuación)
    • En la copia aquí, puede considerar temporalmente las tuplas con elementos variables como mutables.
  • Tipos inmutables : Número (número), Cadena (cadena), Tupla (tupla) [todos los tipos de contenedor excepto tuplas]
  • Tipos de variables : Lista (lista), Diccionario (diccionario), Conjunto (colección) [Tipo de contenedor de combate]
  • Tipos que no son de contenedor : Número (número), Cadena (cadena) [ambos tipos inmutables]
  • Tipo de contenedor : Lista (lista), Diccionario (diccionario), Tupla (tupla) [tipos de variable excepto tuplas]
  • Para facilitar la comprensión, puede echar un vistazo al siguiente diagrama esquemático reproducido de otros.

"Copia" de tipos inmutables

Los tipos inmutables son tipos que no son contenedores, excepto las tuplas . No se copian. Copiar usando el módulo de copia es una asignación directa y transferencia de direcciones de memoria.

  • Para comprender algunas razones de diseño para copiar, primero debemos resolver la razón de la asignación directa para lograr "copiar"
  • porqueLa necesidad de copiar es esperar que las dos variables no interfieran entre sí, y una nueva. El tipo inmutable de "modificado" para haber logrado la independencia de ambos (su "modificación" es recrear una variable, la nueva variable para apuntar al nuevo objeto, la vieja variable aún apunta a los viejos objetos). Por lo tanto, no es necesario abrir un nuevo espacio para copiar el mismo contenido, solo apunte directamente a la misma dirección.

Asignación directa

  • Verificación en la figura:
a = "a"
b = a # 直接赋值,进行“拷贝”
print(b is a)
b = "b" # “修改”又是直接赋值了,因为它们无法修改
print(a)
print(b)
print(b is a)

Verdadero
a
b
Falso

  • Las tuplas de tipos inmutables también se asignan directamente . Pero las tuplas con elementos variables son especiales , consulte la siguiente sección.

-> Entonces, en la siguiente copia del tipo de variable / tipo de contenedor, los subelementos del tipo inmutable se pueden asignar directamente y pasar la dirección de memoria.

Cabe señalar que la asignación directa aquí es apuntar directamente las etiquetas de variable antigua y nueva al mismo objeto . "Modificar" se refiere a "modificar" una etiqueta de variable sin pasar a otra etiqueta de variable. Para que los dos sean independientes y no afecten.


Asignación directa de tipos mutables

Lo anterior es la asignación directa de tipos inmutables, aquí hay un vistazo a la asignación directa de tipos mutables. Esta es la etiqueta de variable que apunta al mismo objeto. Utilice siempre el mismo objeto y no cumplirá con los requisitos de copia:
Asignación directa de tipos mutables

(No quiero editar la imagen, solo entiendo el significado. Los tipos de contenedor son variables excepto las tuplas. La "copia" de las tuplas se discutirá por separado)


Copia profunda de tipo variable y copia superficial

Sus copias profundas y superficiales son [ crear un nuevo objeto ], pero los elementos secundarios directos apuntan a diferentes puntos. Aquí, las etiquetas de variable nuevas y antiguas apuntan a dos objetos diferentes . (La tupla es especial, preste atención más tarde)

  • Por lo tanto, ¡la futura modificación de estas dos variables no interferirá entre sí! Esto también puede ser simplemente analógico del diagrama de "Asignación directa de tipo inmutable" anterior: la variable AB se reemplaza con el objeto AB (se corresponden entre sí); estos dos objetos son contenedores y apuntan a muchas "cadenas".
import copy
aList = ["你", "好", 1, [1, 2, 3]]
bList = copy.copy(aList) # 浅拷贝:拷贝了所有元素的内存地址到一个新list对象里
cList = copy.deepcopy(aList) # 深拷贝:在浅拷贝的基础上,还递归为容器元素创建新对象拷贝内容

En la asignación directa, utilizamos las etiquetas de variable antiguas y nuevas como punto de referencia para ver la modificación del contenido de la variable. Aquí, continuamos mirando la etiqueta de variable, que apunta a los objetos contenedores nuevos y antiguos. Cuando los elementos del objeto contenedor son de tipo inmutable, siguiendo la lógica antes mencionada, el objeto recién creado da a los elementos del objeto contenedor nuevas direcciones para no afectarse entre sí.

  1. Copia superficial, debido a que el tipo inmutable "你", "好", 1sub-lista modificar nuevos objetos se dan nueva dirección, de modo que la interferencia entre los dos, pero modificados [1, 2, 3]no creará un nuevo objeto, por lo que este ha sido a la vez referencia a la misma, influyen mutuamente.
    Inserte la descripción de la imagen aquí
  • Copia superficial en el diccionario: cree dos objetos de diccionario, cree un nuevo objeto * para la clave , pero copie la dirección de memoria del valor , y sus valores se comparten (debe comprender el diagrama de memoria del diccionario). Si los valores tienen tipos de variables, aún se afectan entre sí.
    • Se crea un nuevo objeto para la clave: por ejemplo, el diccionario A, B: B es una copia superficial de A, si se elimina una clave de B en este momento, la clave correspondiente en A no tiene ningún efecto. Se realiza la independencia inicial de los dos diccionarios y se comprende la necesidad de este tipo de copia superficial.
    • Consulte el diagrama detallado en el punto 4. Se recomienda leer primero los puntos 1 y 2.
  1. En la copia profunda, la recursividad se realiza para crear un nuevo contenido de copia de objeto para el elemento contenedor. Para que las dos variables nunca interfieran entre sí.
    Inserte la descripción de la imagen aquí
  • Copia profunda en el diccionario: se crean nuevos objetos para claves y valores (los tipos inmutables siguen copiando direcciones de memoria), y los dos no interfieren entre sí.
  1. Caso especial: tupla
  • Las tuplas son tipos inmutables y no deberían poder copiarse, ya que pasan direcciones de memoria .
  • Lo especial es que las tuplas con elementos de tipo variable se pueden copiar en profundidad , crear un nuevo objeto y crear de forma recursiva un nuevo objeto para el elemento variable (todavía no tiene una copia superficial, copy.copy()pero también transfiere la dirección de memoria )
  1. Después de comprender las copias profundas y superficiales de la lista anterior, no es difícil comprender las copias profundas y superficiales del diccionario por analogía.

Copia superficial del diccionarioCopia profunda del diccionario

  1. Acerca de la prueba anterior: Omitida. No olvide los puntos de conocimiento. .

Información reimpresa

  1. Asignación directa: dirección de memoria de paso
    Asignación directa

  2. Copia superficial: crea un nuevo objeto, copia todas las direcciones de memoria
    Copia superficial

  3. Copia profunda: cree nuevos objetos , copie direcciones de memoria de tipos inmutables y cree de forma recursiva nuevos objetos con tipos variables .
    Copia profunda!

  4. La diferencia entre copia profunda y copia superficial de tuplas inmutables y listas mutables

La diferencia entre copia profunda y copia superficial de tuplas inmutables y listas mutables
Aquí, la primera parte, toda la tupla es una asignación directa inmutable, así es True;
la segunda parte, un tipo de copia variable, una copia superficial o una copia profunda, su contenido es el mismo que ==es True; y son Copiar nuevos objetos, por lo que la dirección de memoria ==es False.

Donde se usa la copia

Python generalmente usa copia superficial de forma predeterminada. Los siguientes ejemplos están esperando a ser agregados.
como:

  • Rebanadas [:]con una copia superficial
  • Parámetros de palabras clave: **extrase utiliza una copia superficial, la tecla de eliminación dentro de la función no tiene ningún efecto sobre el valor original en el exterior, pero el valor del tipo de variable se comparte

Reimpresión de referencia / imagen: Copia profunda y copia superficial de Python gráfico-Proyecto Tian Xiao- 博客 园

Supongo que te gusta

Origin blog.csdn.net/zsq8187/article/details/109907066
Recomendado
Clasificación