有没有“中等”的拷贝?或者:如何精细地控制拷贝的“深度”?

2024-05-23 20:39:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一本字典。字典键是整数,值是对象列表。你知道吗

我希望能够以这样一种方式复制字典,即引用完全相同的对象,但不同的列表。你知道吗

当我使用普通拷贝时口述副本()或复制。复制(dict)--我对复制词典中的列表所做的任何更改也会更改原始词典的列表。你知道吗

但是,当我使用复制.deepcopy(dict),它一直在做新的对象,因此我不能,例如,当我从复制的字典列表中删除特定对象时,使用原始字典的列表作为“待办事项”,或者对复制的字典列表进行任何其他需要与原始对象进行比较的更改。你知道吗

关于“copy”模块(https://docs.python.org/2/library/copy.html)的文档似乎没有提到任何中间选项,也没有提到调整深度的方法。你知道吗

这样的选择、功能或什么都不存在吗?如果不是,我只是从错误的角度思考问题吗?例如,我设想,如果我遍历字典并以这种方式手动“复制”内容,我可能能够实现所需的行为(但这似乎有点冗长!)。你知道吗


Tags: 模块对象https列表字典方式副本事项
3条回答

您需要创建list的副本(这是您的dict的值)。即使没有copy.copy(),您也可以这样做。你知道吗

new_list = list(old_list)

将创建具有相同内容的copyold_list,并将其存储为new_list。你知道吗

因此,创建新dict的表达式应该是:

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

其中my_dict是您的原始词典

您只需实现自己版本的“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

您可以创建实现__deepcopy__方法的dict子类作为浅拷贝,并在您希望deepcopy停止的级别使用该子类(而不是本机dict)。你知道吗

相关问题 更多 >