覆盖两个for循环函数中的列表(Python)

时间:2015-08-06 17:57:03

标签: python arrays

所以让我们考虑一下我有以下数组:

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。任何人都可以向我解释发生了什么?

1 个答案:

答案 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]]

这也将复制作为元素的列表。