【问题标题】:Best way to partially deep copy a dictionary in Python?在 Python 中部分深度复制字典的最佳方法?
【发布时间】:2016-06-17 12:43:18
【问题描述】:

我有一个表示为dict 的图,其中每个键是(自定义)Node 类的一个实例,值是Nodes 的实例集。所以,基本上,图表看起来像这样,但更大:

g = { Node1 : {Node2, Node3}, Node2 : {Node4}, Node3: set(), Node4 : {Node1} }

简而言之我想做的事:我想任意更改字典,然后将其恢复为更改之前的原始值。

我可以对此图进行一系列转换,但我无法事先知道我想要进行哪种转换。转换将始终:

  • 一键删除
  • 添加两个新顶点
  • 改变大约 1/n 条边

由于我不知道要进行哪种转换,因此我想对同一个图执行每个转换,然后选择一个。

一个明显的习语可能是:

  • 将字典复制到临时字典 (temp = g)
  • 对每个转换重复t
    • 在图g上执行转换t以形成图g'
    • 记下有关图表g' 的信息以备后用
    • 设置g = temp 将图形恢复到已知良好状态

这不起作用,因为复制字典只执行浅拷贝,因此对g 的所有更改也会在temp 上执行。

我可以使用deepcopy,但即使这样也无法正常工作。我想deepcopy实际字典g,但是gNodes)的值中的键和元素不能被深度复制,因为在我的转换中,我会寻找在@987654339中的元素@ 但不在 temp 中,因为它们现在是新对象。

我可以尝试为Node 类重新定义deepcopy,这工作,但它非常hackish,我确实需要使用 deepcopy 来执行我的转换t

以下是一个最小的工作示例,它可以完成我想要它做的事情 - 但在某种程度上我不想因为我需要创建一个解决方法来让 deepcopy 在以下情况下实际工作我需要它。此外,进行转换的代码全部使用gg 中的实际Nodes,就像现在一样,因此不必进行太多更改就可以了。

有没有更好的方法来做到这一点? (所有prints 都应该是True

from copy import deepcopy

class MyClass:

    def __init__(self, value):
        self.value = value

    def __repr__(self):
        return str(self.value)

    def __deepcopy__(self, memo):
    # do not rly deep copy plx
        return self

    class1 = MyClass(1)
    class2 = MyClass(2)
    class3 = MyClass(3)

    dict_class = { class1 : {class2, class3}, class2 : {class3}, class3 : {class1}}

    #### Want to create a copy of the dictionary with exact same objects... ####

    dict_class_copy = deepcopy(dict_class)

    print(dict_class)
    print(dict_class_copy)

    print(class1 in dict_class and class2 in dict_class and class3 in dict_class)
    print(class1 in dict_class_copy and class2 in dict_class_copy and class3 in dict_class_copy)

    dict_class.pop(class2)
    dict_class[class1].remove(class3)

    # don't want to change original dictionary key values
    print(class2 not in dict_class and class2 in dict_class_copy)

    # this breaks w/o deepcopy!
    print(class3 not in dict_class[class1] and class3 in dict_class_copy[class1])

    # reassign it back 
    dict_class = dict_class_copy 

    # i want this back!
    print(class2 in dict_class)
    print(class3 in dict_class[class1])

【问题讨论】:

    标签: python dictionary copy deep-copy


    【解决方案1】:

    通过复制键和制作集合的副本来制作字典的“1 级深度”副本。替换这个:

    dict_class_copy = deepcopy(dict_class)
    

    用这个:

    dict_class_copy = {k:set(v) for k,v in dict_class.items()}
    

    你的测试通过了。

    【讨论】:

    • 我不得不修改我的代码以在我的循环中不断地执行此操作,但这绝对帮助了我。谢谢。
    猜你喜欢
    • 2011-01-24
    • 2012-01-15
    • 2011-06-25
    • 2017-04-16
    • 1970-01-01
    • 2017-11-22
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    相关资源
    最近更新 更多