【问题标题】:Why does value appended to list change dynamically?为什么附加到列表的值会动态变化?
【发布时间】:2022-01-08 01:09:55
【问题描述】:

Python 版本:3.9.5

我的代码:

cells = [[i, i] for i in range(3)]
steps = []

for t in range(2):
    for i in range(len(cells)):
        xrand = random.randint(-5, 5)
        yrand = random.randint(-5, 5)
        cells[i][0] += xrand
        cells[i][1] += yrand
    steps.append(list(cells))
    print(steps)

实际输出:

[[[3, 3], [2, 3], [6, 3]]]
[[[4, 7], [-3, 2], [8, 3]], [[4, 7], [-3, 2], [8, 3]]]

预期输出:

[[[3, 3], [2, 3], [6, 3]]]
[[[3, 3], [2, 3], [6, 3]], [[4, 7], [-3, 2], [8, 3]]]

我每次都在外部循环中更改列表 cells 的值,并将修改后的列表附加到 steps 列表中。正如您在输出中看到的那样,在第二次迭代中,cells 的第一个元素也被修改了,即使我只是将一个元素附加到列表中。

steps 的第一个元素是上一次迭代的cells 列表。但是在第二次迭代中,两个元素都会动态变化,即使我只是附加一个元素,所以第一个元素不应该受到影响。

为什么会发生这种情况以及如何克服?

【问题讨论】:

    标签: python python-3.x list dynamic


    【解决方案1】:

    list(cells)创建一个浅拷贝,因此修改cells的可变内容也会改变浅拷贝的内容——或者说,浅拷贝的内容真的是同一个对象 作为cells的内容。

    你想要的是一个深拷贝:

    import copy
    
    cells = [[i, i] for i in range(3)]
    steps = []
    
    for t in range(2):
        for i in range(len(cells)):
            xrand = 1
            yrand = 1
            cells[i][0] += xrand
            cells[i][1] += yrand
        steps.append(copy.deepcopy(cells))
        print(steps)
    

    输出:

    [[[1, 1], [2, 2], [3, 3]]]
    [[[1, 1], [2, 2], [3, 3]], [[2, 2], [3, 3], [4, 4]]]
    

    我已将 random.randint 部分替换为静态值,因此演示的输出更少……随机。

    【讨论】:

      【解决方案2】:

      列表被原地操作

      这是因为列表是通过对磁盘上真实对象(存储位置)的引用来操作的。请参阅以下示例:

      l = [2]
      x = [l, l]
      print(x)
      >>> [[2], [2]]
      l[0] = 4
      print(x)
      >>> [[4], [4]]
      

      您可以通过使用新变量或 copy.deepcopy() 来克服这个问题

      >>> import copy
      >>> l = [2]
      >>> x = [copy.deepcopy(l), l]
      >>> print(x)
      [[2], [2]]
      >>> l[0] = 4
      >>> print(x)
      [[2], [4]]
      

      【讨论】:

        猜你喜欢
        • 2021-03-10
        • 1970-01-01
        • 2012-07-20
        • 2010-11-22
        • 1970-01-01
        • 1970-01-01
        • 2023-03-13
        • 1970-01-01
        • 2022-01-24
        相关资源
        最近更新 更多