有 "medium" 副本这样的东西吗?或者:如何精细控制文案"depth"?

Is there such a thing as a "medium"-copy? Or: how to finely control "depth" of copy?

我有一本字典。字典键是整数,值是对象列表.

我希望能够以这样的方式复制字典,以便我可以回头引用确切的相同的对象,但不同的列表.

当我使用普通副本时——dict.copy() 或 copy.copy(dict)——我对副本字典中的列表所做的任何更改也会更改原始字典的列表。

但是,当我使用 copy.deepcopy(dict) 时,它会一路生成新对象,因此我不能,例如,将原始字典的列表用作 "to-do"当我从复制的字典列表中删除特定对象,或对需要与原始对象进行比较的复制字典列表进行任何其他类型的更改时。

"copy" 模块 (https://docs.python.org/2/library/copy.html) 的文档似乎没有提到任何类型的中间选项,或者某种调整深度的方法。

是否存在这样的选项或功能或诸如此类的东西?如果不是,我只是从错误的角度思考问题吗?例如,我想如果我遍历字典并以这种方式手动 "copied" 事情,我可能能够实现所需的行为(但这似乎很啰嗦!?)。

你可以只实现你自己的版本 "medium"-copy:

import copy


def mediumcopy(value):
    return dict(
        (key, copy.copy(val))
        for key, val in value.iteritems())

z = {'a': [[1], [2]]}
zcopy = mediumcopy(z)
assert id(z) != id(zcopy)  # True
assert id(z['a']) != id(zcopy['a'])  # True
assert id(z['a'][0]) == id(zcopy['a'][0])  # True

Python 3 版本:

def mediumcopy(value):
    return {key: list(val)  # you can still use copy.copy here
            for key, val in value.items()}

z = {'a': [[1], [2]]}
zcopy = mediumcopy(z)
assert id(z) != id(zcopy)  # True
assert id(z['a']) != id(zcopy['a'])  # True
assert id(z['a'][0]) == id(zcopy['a'][0])  # True

您需要创建 list 的副本(它们对您的 dict 有价值)。即使没有 copy.copy(),您也可以这样做。

new_list = list(old_list)

将创建具有相同内容的old_listcopy,并将其存储为new_list

因此,创建新字典的字典理解表达式应为:

new_dict = {k: list(v) for k, v in my_dict.items()}

其中 my_dict 是您的原始口述。

您可以创建 dict 的子类,将 __deepcopy__ 方法实现为浅拷贝,并在您所处的级别使用该子类(而不是本机 dict)希望深度复制停止。