Reputation: 111
Summary: I created a new list variable by taking a slice of an original one. When I tweak the new list, the previous one also changes, but I'm fairly certain they are two distinct lists! Here's my general method:
1.Create initial list all_info
by calling a function. Each list item is itself a list with 5 elements.
all_info = CrossReference(start_info, RBS_info, promoter_info)
2.Create a new list all_info_mod
by slicing the initial list to remove the first item (I need to do this for later code). Then confirm thet are distinct.
all_info_mod = all_info[1:]
all_info #Shows original list
all_info_mod #Shows sliced list
3.Increment the first 3 elements of each outer list by 1. Then check.
for i in all_info_mod:
for j in range(0, 3):
i[j] += 1
all_info_mod #Successfully altered
all_info #Also altered?!
The initial list is also altered when it shouldn't be. I have tested with simpler examples and get the same result. Perhaps it's a result of my previous code that comes before this? (Can provide more details if needed).
Thanks in advance!
Upvotes: 0
Views: 135
Reputation: 6526
When you do this:
all_info = [[1,2,3], [2,3,4], [5,6,7]]
all_info_mod = all_info[1:]
You perform slicing on all_info
to create a new list all_info_mod
.
The problem is that the elements of all_info
are (references to) lists, so all_info_mod
will contain the copy of the references to lists. The references are copied, so at the end both lists contain references to the same lists.
This explains why when you modifies the lists referenced by the elements of all_info_mod
, you also modify the lists referenced by the elements of all_info
.
Note that if you modify directly an element of all_info_mod
by assignment, i.e. if you replace the reference to a list with another one, then all_info
is not changed:
all_info_mod[1] = [9,9,9]
print(all_info) # [[1, 2, 3], [2, 3, 4], [5, 6, 7]]
print(all_info_mod) # [[2, 3, 4], [9, 9, 9]]
If you really want to duplicate the data in another list, you have to use the method copy.deepcopy(), as follows:
import copy
all_info = ...
all_info_mod = copy.deepcopy(all_info[1:])
Upvotes: 1
Reputation: 60944
This is happening because you're modifying mutable objects that both lists contain references to. Modifying the list you sliced won't change the slice, but modifying a mutable object in that list will also be visible from the other list, because both lists contain the same object.
list_ = [[1, 2, 3], [4, 5, 6]]
slice_ = list_[:]
list_[0] = [7, 8, 9]
print(slice_)
# [[1, 2, 3], [4, 5, 6]]
list_[1].append(0)
print(slice_[1])
# [4, 5, 6, 0]
print(list_[1] is slice_[1]) # The two lists both contain the same list object
# True
Upvotes: 1
Reputation: 1393
You should import copy
module and make a deepcopy
if you don't want changes in original list.
import copy
all_info_mod = copy.deepcopy(all_info[1:])
Upvotes: 3