好的,让我们再试一次。我有1组数据。我想制作2份副本,然后根据不同的列按降序对副本进行排序。然后我想获得各列的累积总和。当我运行以下代码时,我在print(setA [x] [2])上调用的两个实例得到了不同的结果。
set = [[2,2,0],[1,3,0],[3,1,0]]
def getkey_setA (item):
return item[0]
setA = sorted(set, key=getkey_setA, reverse=True)
def getkey_setB (item):
return item[1]
setB = sorted(set, key=getkey_setB, reverse=True)
setA[0][2] = setA[0][0]
setB[0][2] = setB[0][1]
for x in range(1, 3):
setA[x][2] = setA[x-1][2] + setA[x][0]
print(setA[x][2])
for x in range(1, 3):
setB[x][2] = setB[x-1][2] + setB[x][1]
for x in range(1, 3):
print (setA[x][2])
这会产生:
5
6
8
6
但我希望它能产生
5
6
5
6
代替。
答案 0 :(得分:1)
sorted()
创建正在排序的序列的浅副本。这意味着您的嵌套列表不会被复制,只会被引用:
>>> set = [[2,2,0],[1,3,0],[3,1,0]]
>>> setA = sorted(set, key=getkey_setA, reverse=True)
>>> setB = sorted(set, key=getkey_setB, reverse=True)
>>> setA[0] is set[2]
True
>>> setB[2] is set[2]
True
>>> setA[0] is setB[2]
True
因此set
中的最后一个元素与setA[0]
和setB[2]
完全相同的对象。对其中任何一个引用进行更改都会反映在其他引用中:
>>> setA[0][2]
0
>>> setA[0][2] = 42
>>> setB[2]
[3, 1, 42]
>>> set[2]
[3, 1, 42]
这就是运行代码后set
对象(您从中生成已排序的setA
和setB
列表)也更改的原因:
>>> set
[[2, 2, 8], [1, 3, 6], [3, 1, 9]]
您需要创建嵌套列表的正确副本;您可以使用copy.deepcopy()
function创建列表对象的递归副本,也可以在排序时使用生成器表达式:
setA = sorted((subl[:] for subl in set), key=getkey_setA, reverse=True)
setB = sorted((subl[:] for subl in set), key=getkey_setB, reverse=True)
这会轻微复制嵌套列表;这很好,因为那些嵌套列表本身只包含不可变对象。