应用更改后如何比较同一dict?(Python)

应用更改后如何比较同一dict?(Python),python,Python,我有一个问题,我有一个函数,它可能改变或不改变字典的值,我想用另一个函数跟踪这些改变。它看起来像这样: dict_t0 = my_dict function_that_alters_values(my_dict) dict_t1 = my_dict compare_dicts(dict_t0,dict_t1) def compare_dicts(d1, d2): """ Gives the actions necessary for d1 to be equal to d2

我有一个问题,我有一个函数,它可能改变或不改变字典的值,我想用另一个函数跟踪这些改变。它看起来像这样:

dict_t0 = my_dict
function_that_alters_values(my_dict)
dict_t1 = my_dict
compare_dicts(dict_t0,dict_t1)
def compare_dicts(d1, d2):
    """
    Gives the actions necessary for d1 to be equal to d2
    """
    diff = {
      "add": [key for key in d2 if key not in d1],
      "delete": [key for key in d1 if key not in d2],
      "update": {key: d2[key] for key in set(d1) & set(d2) if d1[key] != d2[key]}
    }
    return diff
但是,由于
dict\u t0
只是指向对象
my\u dict
,因此对
my\u dict
所做的任何更改都将应用于
dict\u t0
,这就是我尝试使用

dict_t0 = deepcopy(my_dict)
但是,这给了我以下错误:

RecursionError: maximum recursion depth exceeded

有没有更好的方法来解决我的问题?

也许您可以更改函数,使其在原地不起作用,而是返回新实例:

original = {1: [1, 2, 3], 2: [4, 5, 6]}
new = original

def squareValues(someDict):
    return {k: [i**2 for i in v] for k, v in someDict.items()}

new = squareValues(new)

original
#{1: [1, 2, 3], 2: [4, 5, 6]}

new
#{1: [1, 4, 9], 2: [16, 25, 36]}
编辑

对于
deepcopy
您可以增加递归限制:

sys.setrecursionlimit(5000) # or more if your structure is deeper.
要查看当前递归限制,请使用:

sys.getrecursionlimit()

也许您可以更改函数,使其不在原地工作,而是返回新实例:

original = {1: [1, 2, 3], 2: [4, 5, 6]}
new = original

def squareValues(someDict):
    return {k: [i**2 for i in v] for k, v in someDict.items()}

new = squareValues(new)

original
#{1: [1, 2, 3], 2: [4, 5, 6]}

new
#{1: [1, 4, 9], 2: [16, 25, 36]}
编辑

对于
deepcopy
您可以增加递归限制:

sys.setrecursionlimit(5000) # or more if your structure is deeper.
要查看当前递归限制,请使用:

sys.getrecursionlimit()

对于deepcopy问题,您可以按照@zipa-answer进行操作。然后,为了比较两个DICT,您可以创建如下函数:

dict_t0 = my_dict
function_that_alters_values(my_dict)
dict_t1 = my_dict
compare_dicts(dict_t0,dict_t1)
def compare_dicts(d1, d2):
    """
    Gives the actions necessary for d1 to be equal to d2
    """
    diff = {
      "add": [key for key in d2 if key not in d1],
      "delete": [key for key in d1 if key not in d2],
      "update": {key: d2[key] for key in set(d1) & set(d2) if d1[key] != d2[key]}
    }
    return diff
用法示例:

dict1 = {
  "a": 1, # same
  "b": 2, # different value
  "c": 3, # not present
  #"d": 4 missing
}

dict2 = {
  "a": 1,
  "b": 1,
  "d": 4
}
print(compare_dicts(dict1, dict2))

对于deepcopy问题,您可以按照@zipa-answer进行操作。然后,为了比较两个DICT,您可以创建如下函数:

dict_t0 = my_dict
function_that_alters_values(my_dict)
dict_t1 = my_dict
compare_dicts(dict_t0,dict_t1)
def compare_dicts(d1, d2):
    """
    Gives the actions necessary for d1 to be equal to d2
    """
    diff = {
      "add": [key for key in d2 if key not in d1],
      "delete": [key for key in d1 if key not in d2],
      "update": {key: d2[key] for key in set(d1) & set(d2) if d1[key] != d2[key]}
    }
    return diff
用法示例:

dict1 = {
  "a": 1, # same
  "b": 2, # different value
  "c": 3, # not present
  #"d": 4 missing
}

dict2 = {
  "a": 1,
  "b": 1,
  "d": 4
}
print(compare_dicts(dict1, dict2))

字典有一个.copy()方法,你试过用它代替deepcopy吗?@Dan copy()将创建一个浅拷贝&而不是完整拷贝。因此,这些值是不分开的。您认为如果使用copy(),值的变化会反映出来吗?如果内置的.copy()方法无法解决此问题,您可以使用pickle库保存字典的初始状态:来自
copy
文档的旁注,用于
deepcopy
:“递归对象”(直接或间接包含自身引用的复合对象)可能会导致递归循环。“这可能解释了最大递归深度问题。根据Dan的建议,您也可以查看。字典有一个.copy()方法,您是否尝试过该方法而不是deepcopy?@Dan copy()将创建一个浅拷贝&而不是完整拷贝。因此值不会分开。您认为如果使用copy(),值中的更改会反映出来吗?如果内置的.copy()方法无法解决此问题,您可以使用pickle库保存字典的初始状态:来自
copy
文档的旁注,用于
deepcopy
:“递归对象(直接或间接包含自身引用的复合对象)可能会导致递归循环。”这可以解释最大递归深度问题。根据Dan的建议,您也可以查看。