当我今晚写了一些代码时,我遇到了一个问题,即使它没有阻止我,引起了我的注意,因为我无法理解。所以这是我写的一个函数(不应该是最好的方法,但是没关系......)
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]]
我将测试样本保持不变。也许它来自我写的功能?我不知道......
所以问我的问题:有谁知道为什么?
谢谢:)
答案 0 :(得分: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