python中的累积和在使用for循环求和时给出不同的结果

时间:2016-11-01 09:25:39

标签: python

好的,让我们再试一次。我有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

代替。

1 个答案:

答案 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对象(您从中生成已排序的setAsetB列表)更改的原因:

>>> 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)

这会轻微复制嵌套列表;这很好,因为那些嵌套列表本身只包含不可变对象。