【问题标题】:Subtlety accessing and modifying a multidimensionnal list微妙地访问和修改多维列表
【发布时间】:2012-08-09 01:04:04
【问题描述】:

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

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

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

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

谢谢你:)

【问题讨论】:

    标签: python list python-2.7


    【解决方案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 中的原始行元素

    【讨论】:

    • : 是您索引到列表中的方式,例如c[1:5]。通过执行line[:],您正在使用新元素对列表中的每个元素进行“插入”。实际对象保持不变,但您只需设置新值
    猜你喜欢
    • 2017-11-15
    • 2021-04-25
    • 1970-01-01
    • 2021-11-15
    • 2014-01-23
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多