如何复制Python中函数调用中不会更改的列表

时间:2013-05-14 05:55:37

标签: python python-2.7 nested-lists

我正在研究这些功能(参见this):

def removeFromList(elementsToRemove):
    def closure(list):
        for element in elementsToRemove:
            if list[0] != element:
                return
            else:
               list.pop(0)
    return closure

def func(listOfLists):
    result = []
    for i, thisList in enumerate(listOfLists):
        result.append(thisList)
        map(removeFromList(thisList), listOfLists[i+1:])
    return result

我有一个列表,我想作为参数传递, 但我希望这份清单保持不变。我试过的是:

my_list = [[1], [1, 2], [1, 2, 3]]
print my_list
#[[1], [1, 2], [1, 2, 3]]

copy_my_list = list (my_list)

#This also fails
#copy_my_list = my_list [:]

print id (my_list) == id (copy_my_list)
#False

print func (copy_my_list)
#[[1], [2], [3]]

print my_list
#[[1], [2], [3]]

但它确实改变了我的原始列表。 有什么想法吗?

3 个答案:

答案 0 :(得分:7)

使用copy.deepcopy

from copy import deepcopy
new_list = deepcopy([[1], [1, 2], [1, 2, 3]])

演示:

>>> lis = [[1], [1, 2], [1, 2, 3]]
>>> new_lis = lis[:]                    # creates a shallow copy
>>> [id(x)==id(y) for x,y in zip(lis,new_lis)]
[True, True, True]                     #inner lists are still the same object

>>> new_lis1 = deepcopy(lis)           # create a deep copy
>>> [id(x)==id(y) for x,y in zip(lis,new_lis1)]
[False, False, False]                 #inner lists are now different object

答案 1 :(得分:3)

使用list(my_list)my_list[:],您都会获得列表的浅表副本。

id(copy_my_list[0]) == id(my_list[0])
#  True

所以请使用copy.deepcopy来避免您的问题:

copy_my_list = copy.deepcopy(my_list)
id(copy_my_list[0]) == id(my_list[0])
#  False

答案 2 :(得分:1)

使用元组。 my_list = ([1], [1, 2], [1, 2, 3])

my_list现在是不可变的,只要你想要一个可变副本,你就可以使用list(my_list)

>>> my_list = ([1], [1, 2], [1, 2, 3])
>>> def mutate(aList):
        aList.pop()
        return aList

>>> mutate(list(my_list))
[[1], [1, 2]]
>>> my_list
([1], [1, 2], [1, 2, 3])
>>> 

有人引起我的注意,这个解决方案并非万无一失。元组本身不是可变的,但它的元素是(如果它们是可变对象 - 列表是哪个)。