Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to copy a list which will not be changed in function call in Python

I was working on these functions (see 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

I have a list which I want to pass as argument, but I want this list to remain intact. What I tried is:

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

But it does change my original list. Any ideas?

like image 294
hola Avatar asked Dec 20 '22 05:12

hola


2 Answers

Use copy.deepcopy:

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

Demo:

>>> 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
like image 177
Ashwini Chaudhary Avatar answered Apr 28 '23 10:04

Ashwini Chaudhary


both with list(my_list) and my_list[:] you get a shallow copy of the list.

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

so use copy.deepcopy to avoid your problem:

copy_my_list = copy.deepcopy(my_list)
id(copy_my_list[0]) == id(my_list[0])
#  False
like image 44
Thomas Fenzl Avatar answered Apr 28 '23 09:04

Thomas Fenzl