Problema de asignación sobre la lista de listas en Python

Problema de asignación sobre la lista de listas en Python

    Este artículo registra principalmente los problemas encontrados en el proceso de asignación de la lista de lista y resume el conocimiento relacionado con la copia de la lista.

0. Origen del problema

    El motivo de este artículo es que al utilizar la asignación directa de la lista b=alos resultados que se obtienen son diferentes a los esperados, posteriormente se descubrió que al utilizar directamente el signo igual = para asignar valores a la lista provocaría una serie de problemas, por lo que se describen las diferencias entre , y los 赋值tres .浅拷贝深拷贝

1. Método de asignación de lista de lista

    En python, la asignación de objetos es una referencia de objeto simple, que es diferente de C++, como se muestra en el siguiente ejemplo:

a = ['a', 'b', 'c']
b = a   # 采用简单的=赋值
print(a==b)

# 下面是输出结果:
True

    En el caso anterior, b y a son lo mismo, apuntan a la misma pieza de memoria, y b es solo un alias de a, que es una referencia. Podemos usar si a y b son iguales para juzgar, devolver True, indicando que tienen la misma dirección y el mismo contenido.
    Las operaciones de asignación (incluidos los objetos como parámetros y valores de retorno) no abren un nuevo espacio de memoria, simplemente copian la referencia del nuevo objeto. En otras palabras, no hay sobrecarga de memoria aparte del nombre b.
    Modificar a afecta a b; de manera similar, modificar b afecta a a. El siguiente ejemplo trata de modificar b y agregar un nuevo elemento 'd' al final.Al observar los resultados de salida, se encuentra que al modificar la lista b, la lista a también se modificará, porque ambas usan el mismo espacio de memoria.

a = ['a', 'b', 'c']
b = a
b.append('d')
print('a = {}'.format(a))
print('b = {}'.format(b))

# 下面是输出结果:
a = ['a', 'b', 'c', 'd']
b = ['a', 'b', 'c', 'd']

2. copia superficial

    Una copia superficial crea un nuevo objeto cuyo contenido es una referencia al objeto original.
    La copia superficial tiene tres formas: 切片操作, 工厂函数, copy模块la función de copia en. Por ejemplo, para lo anterior a:
    1. Operación de corte: b = a[:]o b = [each for each in a]
    2. Función de fábrica: b = list(a)
    3. Función de copia: b = copy.copy(a)# Al usar , la b generada por la copia superficial import copydel módulo
    ya no es a. El uso es para encontrar que son no es el mismo objeto, y use id para ver, encontró que no apuntan a la misma pieza de memoria. Pero cuando usamos id(x) para x en a e id(x) para x en b, podemos ver que las direcciones de los elementos que contienen son las mismas.
    En este caso, a y b son objetos diferentes, y modificar b teóricamente no debería afectar a a. Por ejemplo b.append([4,5]). El efecto del código es el siguiente:

a = ['a', 'b', 'c', ['yellow', 'red']]
b = a[:]  # 采用了切片操作对列表b进行赋值
b.append('green') # 对列表b执行添加元素操作
print('a = {}'.format(a))
print('b = {}'.format(b))

# 下面是输出结果:
a = ['a', 'b', 'c', ['yellow', 'red']]  # a中的元素不发生变化
b = ['a', 'b', 'c', ['yellow', 'red'], 'green']  # b中增加了一个元素'green'

    Pero cabe señalar que la razón por la cual la copia superficial se llama copia superficial es que solo copia una capa, y hay una lista anidada en A. Si la modificamos, la situación será diferente.
    a[3].append("azul"). Mirando b, encontrará que b también ha cambiado. Esto se debe a que modificó la lista anidada. Modificando el elemento externo modificará sus referencias, haciéndolas apuntar a otras ubicaciones, modificando los elementos en la lista anidada, y la dirección de la lista no cambiará, apuntando a la misma ubicación. el código se muestra a continuación:

a = ['a', 'b', 'c', ['yellow', 'red']]
b = a[:]  # 采用了切片操作对列表b进行赋值
a[3].append('blue')  # 在a列表中的第3个元素中增加元素'blue',由于a[3]本身也是一个列表,从而是在列表后增加了元素'blue',从输出结果中可以看出来。
print('a = {}'.format(a))
print('b = {}'.format(b))

# 下面是输出结果:
a = ['a', 'b', 'c', ['yellow', 'red', 'blue']]
b = ['a', 'b', 'c', ['yellow', 'red', 'blue']]

3. Copia profunda

    La copia profunda solo tiene una forma, la función copy模块en deepcopy.
    Correspondiente a la copia superficial, la copia profunda copia todos los elementos del objeto, incluidos los elementos anidados de varios niveles. Por lo tanto, su sobrecarga de tiempo y espacio es alta.
    También para la, si usa b = copy.deepcopy(a), la modificación de b no afectará a a. Incluso si la lista anidada tiene un nivel más profundo, no tendrá ningún impacto, porque el objeto copiado en profundidad es simplemente un objeto completamente nuevo, que ya no está relacionado con el objeto original. El código de ejemplo es el siguiente:

import copy
a = ['a', 'b', 'c', ['yellow', 'red']]
b = copy.deepcopy(a)   # 采用深拷贝对a进行深拷贝操作
b.append('xyz')
print('a = {}'.format(a))
print('b = {}'.format(b))

# 下面是输出结果:
a = ['a', 'b', 'c', ['yellow', 'red']]   # 使用深拷贝,对b的修改不会影响到a
b = ['a', 'b', 'c', ['yellow', 'red'], 'xyz']

    O usa el siguiente código:

import copy
a = ['a', 'b', 'c', ['yellow', 'red']]
b = copy.deepcopy(a)   # 采用深拷贝对a进行深拷贝操作
a[3].append('crazy')
print('a = {}'.format(a))
print('b = {}'.format(b))

# 下面是输出结果:
a = ['a', 'b', 'c', ['yellow', 'red', 'crazy']]  
b = ['a', 'b', 'c', ['yellow', 'red']]   # 对a的修改不会影响到b

    O usa el siguiente código:

import copy
a = ['a', 'b', 'c', ['yellow', 'red']]
b = copy.deepcopy(a)   # 采用深拷贝对a进行深拷贝操作
a[3].append('crazy')
b.append('dddd')
print('a = {}'.format(a))
print('b = {}'.format(b))

# 下面是输出结果:
a = ['a', 'b', 'c', ['yellow', 'red', 'crazy']]
b = ['a', 'b', 'c', ['yellow', 'red'], 'dddd']

4. Recordatorio sobre la operación de copia

    1. Para los tipos que no son contenedores, como números, caracteres y otros tipos "atómicos", no existe la copia. Todo lo generado son referencias al objeto original.

    2. Si el valor de la variable de tupla contiene un objeto de tipo atómico, incluso si se usa una copia profunda, solo se puede obtener una copia superficial.

5. Referencias

    (1) Explicar minuciosamente la copia superficial y la copia profunda
    (2) Asignación de lista a otra lista_Poco conocimiento de Python: el método de asignación de Lista no puede ser directamente igual a

Supongo que te gusta

Origin blog.csdn.net/weixin_43981621/article/details/123247342
Recomendado
Clasificación