【问题标题】:List being reassigned new values when not explicitly told to do so [duplicate]未明确告知要重新分配新值的列表[重复]
【发布时间】:2015-10-30 08:57:16
【问题描述】:

我正在编写一个程序,该程序会进行许多数学计算,最终生成要绘制的点列表。我在多次迭代中这样做,每次迭代得到一个点,然后将新点用于代码中的下一次迭代。列表conditions_old 保存上次迭代的值。列表conditions_new 是迭代完成后找到的新点。在代码的末尾,列表设置为彼此相等:conditions_old = conditions_new。这是唯一一次为conditions_old 分配一个值,但用于开始计算的初始条件除外。综上所述,这是我遇到的问题:

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

kCompute = conditions_old[:]

for i in range(3):
    for j in range(3):
        print("conditions_old BEFORE: ", conditions_old[i][j])
        kCompute[i][j] = (conditions_old[i][j] + (1/4))  # This is where things get fishy.
        print("conditions_old AFTER: ", conditions_old[i][j])
        print("kCompute: ", kCompute[i][j])

这是我代码的一小部分。发生的情况是列表conditions_old 将在计算完成后获取kCompute 的值。我的问题是这个;为什么conditions_old 获得kCompute 的新值?还有,这个问题怎么解决?

我以前见过 python 做一些奇怪的事情,但这是我没想到会遇到的。

我目前在 Yosemite 上使用 python 3.4

【问题讨论】:

标签: python macos list


【解决方案1】:

请注意:

kCompute = conditions_old[:]

制作副本。在你的行中:

kCompute[i][j] = (conditions_old[i][j] + (1/4))  # This is where things get fishy.

由于副本的性质较浅,您正在与conditions_old 共享的内部列表之一上设置值。换句话说:

kCompute is conditions_old  # False
kCompute[0] is conditions_old[0]  # True

最简单的解决方法是使用deep copy

from copy import deepcopy

...
kCompute = copy.deepcopy(conditions_old)

【讨论】:

    【解决方案2】:

    您需要在原始列表被编辑之前制作一份深层副本。

    kCompute = conditions_old[:] 只做一个浅拷贝,这两个列表中的列表引用相同的对象。

    你可以做一个深拷贝来避免这个问题:

    from copy import deepcopy
    kCompute = deepcopy(conditions_old)
    

    来自docs

    浅拷贝构造一个新的复合对象,然后(在可能的范围内)将引用插入到原始对象中。

    深拷贝构造一个新的复合对象,然后递归地将在原始对象中找到的对象的副本插入其中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-31
      • 2018-10-24
      • 1970-01-01
      • 2020-03-16
      • 2010-11-09
      • 2019-10-18
      • 1970-01-01
      • 2020-12-26
      相关资源
      最近更新 更多