1

当我今晚写了一点代码时,我遇到了一个问题,尽管它并没有阻止我,但还是引起了我的注意,因为我无法弄清楚。所以这是我写的一个函数(不应该是最好的方法,但没关系......)

def ownShuffle( origin ):
    export  = [[] for i in range( len( origin ) ) ]
    indices = range( len( origin ) )
    for n, item in enumerate( origin ):
        i = random.randrange( len( indices ) )
        export[indices[i]] = item
        indices.remove(indices[i])
    return export

现在有一个这样的测试样本:

c = [[1, 2, 3], 
     [4, 5, 6], 
     [7, 8, 9]]

有问题的部分。我使用几乎相同的代码得到不同的结果。如果这样写:

for i, line in enumerate(c):
    c[i] = ownShuffle(line)

print c
>>> [[3, 2, 1],
     [6, 4, 5],
     [7, 8, 9]]

我得到一个洗牌的名单。但是使用以下代码:

for i, line in enumerate(c):
    line = ownShuffle(line)

print c
>>> [[1, 2, 3], 
     [4, 5, 6], 
     [7, 8, 9]]

我得到测试样本不变。也许它来自我写的函数?我不知道...

所以我的问题是:有人知道为什么吗?

谢谢 :)

4

1 回答 1

1
for i, line in enumerate(c):
    line = ownShuffle(line)

您不断创建一个临时line但它与原始列表不同的引用c。您实际上需要影响其中的值line以反映原始对象。

您可以通过执行以下操作看到它改变了其中的值line

for i, line in enumerate(c):
    line[:] = ownShuffle(line)

这是一种可视化正在发生的事情的方法:

for i, line in enumerate(c):
    id_before = id(line)
    line = ownShuffle(line)
    print id_before, "=>", id(line)
# 4973032728 => 4973032656
# 4973034312 => 4973032656
# 4973034240 => 4973032656

for i, line in enumerate(c):
    id_before = id(line)
    line[:] = ownShuffle(line)
    print id_before, "=>", id(line)
# 4973032728 => 4973032728
# 4973034312 => 4973034312
# 4973034240 => 4973034240

在第一个中,您可以看到它始终是一个临时对象。而在第二个中,该行仍然是您的原始行元素c

于 2012-08-09T01:08:48.700 回答