Python。全局命名空间的列表通过函数被无意地修改了

0 人关注

我在Python中遇到了一个可能是非常基本的问题。但是,如果有人能帮助我理解这里发生的事情,我将非常感激。

我的代码如下。

purchaseprices = {'Stock_A': [[10, 4.21],[20, 5.23], [5, 8.32]],
                  'Stock_B': [[5, 8.23],[15, 7.42], [10, 7.53]]}
def update_purchaseprices(name, number_of_shares):
    remaining_number_of_shares = number_of_shares
    updated_purchaseprices = purchaseprices[name][:]
    indices_to_delete = []
    for i in range(len(updated_purchaseprices)):
        if updated_purchaseprices[i][0] < remaining_number_of_shares:
            remaining_number_of_shares -= updated_purchaseprices[i][0]
            indices_to_delete.append(i)
        else:
            updated_purchaseprices[i][0] = updated_purchaseprices[i][0] - remaining_number_of_shares
            break
    updated_purchaseprices = [i for j, i in enumerate(updated_purchaseprices) if j not in indices_to_delete]
    return updated_purchaseprices
name = "Stock_A"
number_of_shares = 34
print(purchaseprices['Stock_A'])
updated_purchaseprices = update_purchaseprices(name, number_of_shares)
print(updated_purchaseprices) # this works as expected
print(purchaseprices['Stock_A']) # why did the original list got changed as well?

以下是我想做的事情。我有一个原始的清单,它被存储在一个叫做purchaseprices的字典里。这个列表可以通过purchaseprices['Stock_A’]访问。现在我试图写一个函数来返回一个叫做 updated_purchaseprices 的列表,它基本上是原始列表的一个修改版本。为了不改变原始列表,我通过包含updated_purchaseprices = purchaseprices[name]:对其进行了复制。不幸的是,我的代码也改变了原始列表。谁能告诉我为什么会发生这种情况?

1 个评论
[:] 只使一个 浅层复制 列表的内部子列表仍然与原始对象共享。 copy.deepcopy() 将是这里的一个解决方案。
python
list
mutable
LuckyLuke
LuckyLuke
发布于 2022-02-10
1 个回答
mozway
mozway
发布于 2022-02-10
已采纳
0 人赞同

你可能知道,因为你使用了 [:] ,一个列表是可变的,你需要在你的函数中采取一个拷贝。但是这个副本仍然包含原始对象(子列表)。

You need to copy those too!

updated_purchaseprices = purchaseprices[name][:]

with:

updated_purchaseprices = [l.copy() for l in purchaseprices[name]]