开发者

Trying to duplicate a list and modify one version of it in Python 2 [duplicate]

开发者 https://www.devze.com 2023-03-28 09:39 出处:网络
This question already has answers here: How do I clone a list so that it doesn't change unexpectedly after assignment?
This question already has answers here: How do I clone a list so that it doesn't change unexpectedly after assignment? (24 answers) Closed 9 years ago.

I want to duplicate a list and modify the duplicate, but when I try this, I end up modifying the original as well.

A highly simplified version of my problem:

list = [2,3,6,8,9,6,7,4,56,8,9,6,7,8]

new_list = list

new_list[2] = 'n'

print list
print new_list

I only want to change item 2 of the new list, but when I try this, both the new list and the old list change to:

[2,3,'n',8,9,6,7,4,56,8,9,6,7,8]

Is th开发者_JS百科ere something quite fundamental I'm missing here?

I can make it do what I want if I add each item of the list to the next list one by one:

list = [2,3,6,8,9,6,7,4,56,8,9,6,7,8]

new_list = []

for item in list:
    new_list.append(item)

new_list[2] = 'n'

print list
print new_list

If I do that, only the new_list changes, but is there a more straight-forward way?


To make a new copy of your list, try:

newList = list(oldList)

Or more cryptic concise via slicing:

newlist = oldList[:]

Just assigning oldList to newList will result in two names pointing to the same object, like so:

Trying to duplicate a list and modify one version of it in Python 2 [duplicate]

Generic object copying functions are provided by the copy module. (Image taken from: http://henry.precheur.org/python/copy_list).


Yes, you are missing something fundamental. Python will never make a copy of a object, unless you explicitly ask for it, as in myList[:].

Whenever you use =, as in mylist = [2,3,4], you assign the name on the left to the value on the right. In this case you have a value, [2,3,4] (a literal) and you give a new name to this particular list, "mylist".

The same happens when you write new_list = mylist: On the right hand side is a value, but this time it's given by its name. Python looks this name up and finds the existing list. Then this list gets a new name, "newlist", but you still have only one list (with two names for it).


Use new_list = a_list[:] to make a shallow copy of a_list:

a_list = [2,3,6,8,9,6,7,4,56,8,9,6,7,8]    
new_list = a_list[:]    
new_list[2] = 'n'    
print a_list
print new_list

yields

[2, 3, [6, 8], 9, 6, 7, 4, 56, 8, 9, 6, 7, 8]
[2, 3, [6, 'n'], 9, 6, 7, 4, 56, 8, 9, 6, 7, 8]

Think of variable names as references which point at objects. When you say new_list = a_list you are telling Python to make new_list point to the same object that a_list points at. This is why modifying new_list also modified a_list.


PS. Resist the temptation to name a list list. This overrides the builtin definition for the list function.

PPS. new_list = a_list[:] creates a shallow copy. If

a_list = [1, 2,[3,6]]
new_list = a_list[:]

then

new_list[2][1] = 'n'

would modify the sublist in both a_list and new_list. If you want do a deep copy then use

import copy
new_list = copy.deepcopy(a_list)

instead.


When you're doing

new_list = list

your new_list isn't actually a new list, it's a new reference to the old list.

You can create a copy with slice notation:

>>> l = [1, 2]
>>> l2 = l[:]
>>> l2[0]=42
>>> l
[1, 2]
>>> l2
[42, 2]

And also, don't use list as a variable name, it conflicts with builtin list type.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号