在 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 解决方案已经存在的情况下练习之外,没有什么理由这样做.
我正在阅读 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 解决方案已经存在的情况下练习之外,没有什么理由这样做.