我在理解和解决以下列表、排序和索引问题时遇到问题。这是代码示例:
import random as rdm
a=[]
for i in range(3):
a.append([i,rdm.randint(-5,5)])
print a
b = sorted(a,key=lambda a:a[1])
print b
c = []
for j in range(len(b)):
c.append(b[j])
print c
c[0][1] = 0
print a
print b
print c
注意更改“C”的一个值如何更改“b”和“a”。我怎样才能防止它发生?换句话说。我不希望“a”的值改变,无论“b”或“c”发生什么
在您的代码中,当您编写:
c.append(b[j])
您正在向
c
添加对对象 b[j]
的引用。
如果您希望
b
和 c
独立于 a
,则必须对对象进行深复制。
import copy
b = sorted (copy.deepcopy(a), lambda a : a[1])
c.append(b[j])
在 c
中添加对对象 b[j]
的引用。
此后,更改
c[j]
会更改 b[j]
。
为了避免这种情况,请生成 b[j]
的副本:
c.append(copy.copy(b[j]))
这需要import copy
。
事实上,Python 倾向于使用引用而不是复制元素,但有某些例外(例如,dict
.copy
、切片、sorted()
、dict .get()
生成浅拷贝)。你会写 d=b
吗,它们会指向同一个列表(列表)。更多:哪些命令/方法返回深拷贝/浅拷贝/原始?
如果
b[j]
是一个嵌套列表而不是列表(例如,[[1,2,3],[4,5,6]]
),它的元素将是指向下一级列表(指向列表[1,2,3]
和[4,5,6]
)的指针(引用)。然后 copy.copy(b[j])
将生成该指针列表的副本 (c[j]
)。更改 c[j]
不会影响 b
,但在此之前更改 c[j][k]
会影响 b[j][k]
。
使用
copy.deepcopy
而不是 copy.copy
始终使结果完全独立,因为它递归地复制所有内容(还有嵌套列表)。
正如 Storyteller 所写,
b
也取决于 a
,除非您对 a
而不是 a
的副本进行排序:
b = sorted(copy.deepcopy(a), lambda a : a[1])
。
确实,
sorted()
产生浅拷贝,因此第二层不是被复制而是被指向。对于非嵌套列表,浅拷贝足以实现独立性。