所以让我们考虑一下我有以下数组:
arr1 = [[1,1],[2,1]]
现在,我构建了以下函数:
def func(mylist):
print(mylist)
List = list(mylist)
for i in range(2):
for j in range(2):
List[i][j]=0
print mylist
print List
return mylist
然后,当我在arr1上调用我的函数时,初始数组被修改(mylist)。 这真是一种奇怪的行为,因为我只是在复制mylist 修改复制的数组List。任何人都可以向我解释发生了什么?
答案 0 :(得分:0)
不知道为什么人们对这个问题进行了贬低,这是非常有效的。
现在,请考虑一下:
>>> mylist1 = [(1,2), (3,4)]
>>> mylist2 = list(mylist1)
>>> mylist1
[(1, 2), (3, 4)]
>>> mylist2
[(1, 2), (3, 4)]
>>> mylist2[0] = (0, 0)
>>> mylist1
[(1, 2), (3, 4)]
>>> mylist2
[(0, 0), (3, 4)]
如您所见,list()
创建了列表的副本,但此副本不是“深层”副本,如果列表包含可变对象(列表,词典或对象),则副本将只是复制对这些对象的引用而不是它们上的内容。例如:
>>> mylist1 = [[1,2], [3,4]]
>>> mylist2 = list(mylist1)
>>> mylist2[0][0] = 0
>>> mylist2
[[0, 2], [3, 4]]
>>> mylist1
[[0, 2], [3, 4]]
这是因为对第一个元素列表的引用被复制到新列表,而不是它的内容或列表的完整副本,它仍然是相同的列表。
如前所述,使用copy.deepcopy
:
https://docs.python.org/3/library/copy.html#copy.deepcopy
你可以在那里阅读:
浅层复制和深层复制之间的区别仅与复合对象(包含其他对象的对象,如列表或类实例)相关:
- 浅复制构造一个新的复合对象,然后(尽可能)将对它的引用插入到原始对象中找到的对象。
- 深层复制构造一个新的复合对象,然后以递归方式将副本插入到原始对象中找到的对象。
您的特殊情况的另一个选择是使用这样的列表理解:
>>> mylist1 = [[1,2], [3,4]]
>>> mylist2 = [list(elem) for elem in mylist1] # < This one
>>> mylist1
[[1, 2], [3, 4]]
>>> mylist2
[[1, 2], [3, 4]]
>>> mylist2[0][0] = 0
>>> mylist1
[[1, 2], [3, 4]]
>>> mylist2
[[0, 2], [3, 4]]
这也将复制作为元素的列表。