当我今晚编写一些代码时,我遇到了一个问题,尽管它没有阻止我,但引起了我的注意,因为我无法弄清楚。所以这是我编写的一个函数(不应该是执行此操作的最佳方法,但没关系......)
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]]
我得到的测试样本没有变化。也许它来 self 写的函数?我不知道...
所以我的问题是:有人知道为什么吗?
谢谢:)
最佳答案
for i, line in enumerate(c):
line = ownShuffle(line)
您不断创建临时行
,但其引用与原始列表c
不同。实际上,您需要影响 line
内部的值,以使其反射(reflect)原始对象。
您可以看到它通过执行以下操作来更改同一行
内的值:
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
关于python - 巧妙地访问和修改多维列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11875392/