List的功能比较有意思,其中aliasing的功能对我这个新手来说,很具有迷惑性。
一、copy简单的list:
在写Sudoku的程序的时候,我想到用.sort
的功能来比较。但是.sort
一旦用过,原来的list就被修改了。因此需要把最初的list来copy一份。
SO上有提供很多常见的方法:
list_copy = list_original[:]
list_copy = list(list_original)
上面这两种方法都很见效,但是!只是适用于比较简单的list。对于多个lists嵌套的复杂list,是完全没有效果的。譬如:
def is_sorted(x):
x1 = x[:] # 或者 x1 = list(x)
print x1
x1.sort()
print x1
print x, "\n\n"
is_sorted([1, 3, 2])
"""
Output:
[1, 3, 2]
[1, 2, 3]
[1, 3, 2]
对于简单的list,这个方法还是很有效的,x1被修改了,但是x没有变。
"""
def is_sorted2(x):
x1 = x[:]
print x1
for item in x1:
item.sort()
print x1
print x, "\n\n"
is_sorted2([[1, 3, 2],[1, 3, 0, 2]])
"""
Output:
[[1, 3, 2], [1, 3, 0, 2]]
[[1, 2, 3], [0, 1, 2, 3]]
[[1, 2, 3], [0, 1, 2, 3]]
对于复杂的list,这个方法就完全没有效果了。
x的结果还是因为x1的改变而改变了。
"""
二、针对复杂的lists如何avoid mutation
没啥好办法,最简单的就是用import copy里面的deepcopy
。顾名思义,深层复制,完全复制。
from copy import deepcopy
def is_sorted3(x):
x1 = deepcopy(x)
print x1
for item in x1:
item.sort()
print x1
print x, "\n\n"
is_sorted3([[1, 3, 2],[1, 3, 0, 2]])
"""
Console:
[[1, 3, 2], [1, 3, 0, 2]]
[[1, 2, 3], [0, 1, 2, 3]]
[[1, 3, 2], [1, 3, 0, 2]]
"""
所以,问题圆满解决啦~ Lists这个磨人的小妖精搞定了XD
另:官方文档对于copy module的介绍:
8.17. copy — Shallow and deep copy operations
三、为啥会如此复杂?
参考说明:
Henry Prêcheur: Python: copying a list the right way
python-course.eu: Shallow and Deep Copy
四、利用deepcopy的解决示例:
Sudoku game