在 Python 中,要制作一个可变对象的两个或多个副本,除了 deepcopy 的 deepcopy(带备忘录)之外,还有其他方法吗?

In Python, to make two or more copies of a mutable object, is there a way to do that other than a deepcopy of a deepcopy (with memo)?

我正在阅读 deepcopy,由于使用了记忆,看起来同一个可变对象的 deepcopy 都引用了第一个 deepcopy 产生的同一个对象(如果这有意义的话)。 (以下问题和代码的灵感来自 this。)

from copy import deepcopy

a = [1,2,3]
memo = {}
b = deepcopy(a,memo)
print(memo)
# Output was
# {140324138116224: [1, 2, 3], 140324138884096: [[1, 2, 3]]}
# The ids that are the keys in the memo dictionary above may or may not be different 
# every time you run the code. In any case, getting the key for value [1, 2, 3] below:
key = list(memo.keys())[0]        # key is now 140324138116224 in this code run

让我们对列表“a”进行另一个深度复制。根据 memoization works 的方式,c 被分配了 b 所指的同一个对象。

c = deepcopy(a, memo)               # So is this really another deepcopy of "a", intuitively speaking?
print(id(c) == id(b))               # Output is True, so "c" and "b" refer to the same object.
print(id(c) == id(memo[key]))       # Output is True. 
                                    #According to the above link, "c" is created by memo.get(key), 
                                    # so it makes sense that the above returns True
b.append(4)
print(c)                            #We appended to "b", yet this will output [1, 2, 3, 4]

因此,如果我想对一个可变对象进行多次深度复制,看来我必须这样做

a = [1, 2, 3]
b = deepcopy(a, memo)
c = deepcopy(b, memo)
# etc.

像那样把它们串起来?没有别的办法吗?例如,如果我出于某种原因在两者之间改变“b”怎么办,比如

a = [1, 2, 3]
b = deepcopy(a, memo)
# Do some mutating stuff to "b", like
b.append(4)

# Let's say I now want another deepcopy of "a", and not of "b", since I already did some stuff to "b".
c = deepcopy(a, memo)        
# But the above seems to be not what I want because this will just give me a reference to the 
# same object that "b" refers to.
print(c)                 # Gives [1, 2, 3, 4], which is not a copy of "a".
c = deepcopy(b, memo)    # Not what I want either because I already did some mutating stuff to b

我知道在现实中,我会在改变“b”之前做 c = deepcopy(b, memo),但我仍然想知道是否有任何其他方法可以处理复制可变对象(使用备忘录) 更直观?

我想人们可能总是不使用记忆,在这种情况下 b = deepcopy(a)c = deepcopy(a) 将引用不同的对象,因此是“a”的直观深度复制,但这看起来很微妙如何使用 deepcopy 会导致截然不同的结果。

感谢您的帮助!

如果您不想在调用之间进行记忆,请不要提供该参数。如果您忽略第二个参数,它会在调用期间在内部创建一个字典。

不过,要回答标题问题,您可以实现自己的递归解决方案,其功能与 deepcopy 相同,但除了在 ready-made 解决方案已经存在的情况下练习之外,没有什么理由这样做.