Python 3.x 为什么对于简单列表,浅复制的行为与深复制相同

Python 3.x 为什么对于简单列表,浅复制的行为与深复制相同,python-3.x,deep-copy,shallow-copy,Python 3.x,Deep Copy,Shallow Copy,我正在理解python中的浅拷贝和深拷贝概念。我观察到大多数//解释这些概念都使用嵌套列表 import copy lst = [[1,2,3],[4,5,6]] b = copy.copy(lst) c = copy.deepcopy(lst) # Shallow copy demo b[0][0] = 9 print(b) # >>> [[9, 2, 3], [4, 5, 6]] print(lst) # >>> [[9, 2, 3], [4,

我正在理解python中的浅拷贝和深拷贝概念。我观察到大多数//解释这些概念都使用嵌套列表

import copy
lst = [[1,2,3],[4,5,6]]
b = copy.copy(lst)
c = copy.deepcopy(lst)

# Shallow copy demo
b[0][0] = 9
print(b)
# >>> [[9, 2, 3], [4, 5, 6]]
print(lst)    
# >>> [[9, 2, 3], [4, 5, 6]]

# Deepcopy demo
c[0][0] = 10
print(c)
# >>> [[10, 2, 3], [4, 5, 6]] 
print(lst)
# >>> [[9, 2, 3], [4, 5, 6]]
通过上面的简单示例,我理解了浅拷贝和深拷贝的概念。但是,当我实现这个概念时,在一个简单的列表(一维列表)上,观察结果是浅拷贝行为就像深拷贝一样

import copy
lst = [1,2,3]
b = copy.copy(lst)
c = copy.deepcopy(lst)

# Shallow copy demo
b[0] = 0
print(b)
# >>> [0, 2, 3]
print(lst)
# >>> [1,2,3]

# Deepcopy demo
c[0] = 9
print(c)
# >>> [9,2,3]
print(lst)
# >>> [1,2,3]
这表明
copy.copy(lst)
的行为不同,它执行深度复制而不是浅层复制


我想了解为什么嵌套列表和简单列表的
copy.copy()
行为不同。此外,如果我必须让浅显副本用于简单列表,我如何实现它

你得到的结果与“深度级别”没有直接关系 这里要记住的最重要的一点是相互关联的概念

列表是可变的,而数值是不可变的。这意味着您可以添加或修改列表中的项目,但这些操作不会创建或销毁列表,它们只会更改列表。您可以使用内置函数
id()
验证,该函数为您提供变量的内存地址:

lst = [1, 2, 3]
print(id(lst)) # the number printed by this...
lst.append(4)
lst[1] = 0
print(id(lst)) # should be the same printed by this one. That tells us that 
               # the variable 'lst' keeps referecing the same object, although
               # the object have changed in form (mutated)
数字是完全不同的,这是有意义的,因为数字类型变量只能 存储单个数值:

a = 5
print(id(a)) # the number printed by this...
a = 6
print(id(a)) # should be different than this one, meaning that a new numeric 
             # value were created and stored in a different memory address
在线

b[0][0] = 9
在第一个示例中,
b[0]
处的列表正在被操作,但它仍然是同一个对象,而且由于
b[0]
只不过是对
lst[0]
处相同列表的引用(因为
b
是一个浅拷贝),当我们打印
lst
时,我们会看到它也发生了变化

在您的实现中,当您分配
b[0]=0
时,python正在创建值
0
,将其存储在新的内存位置,并重写
b[0]
对与
lst[0]
相同值的引用(因为这是数字类型的自然行为)

如前所述,这不一定与复合数据结构的嵌套级别有关, 因为其中一些是不可变的(例如元组),而在您的实现中发生的相同情况也会发生在这个不可变的数据结构中

您可以阅读更多关于
id()
内置函数的信息,以及更多关于 可变和不可变类型


希望这个答案对你有帮助

“浅”与“深”仅在数据结构具有多个深度级别时才起作用。你的整数列表不是这样的。@jasonharper,谢谢你讲清楚了。