Python 列表排序和索引

问题描述 投票:0回答:2

我在理解和解决以下列表、排序和索引问题时遇到问题。这是代码示例:

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”发生什么

python deep-copy
2个回答
1
投票

在您的代码中,当您编写:

c.append(b[j])

您正在向

c
添加对对象
b[j]
的引用。

如果您希望

b
c
独立于
a
,则必须对对象进行深复制

import copy
b = sorted (copy.deepcopy(a), lambda a : a[1])

0
投票

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()
产生浅拷贝,因此第二层不是被复制而是被指向。对于非嵌套列表,浅拷贝足以实现独立性。

© www.soinside.com 2019 - 2024. All rights reserved.