发现一个 python 错误,有人可以解释一下吗?
Found a python bug, can someone explain?
我编写了一个函数来查找两个嵌套词典中的不同键。
answer.
给我很大的启发
def find_diff_keys(d1: dict, d2: dict, not_included_keys:list = [], path=""):
for k in d1:
if k in d2:
if type(d1[k]) is dict:
find_diff_keys(d1[k],d2[k],not_included_keys, "%s.%s" % (path, k) if path else k)
else:
if type(d1[k]) is dict:
not_included_keys.append("%s" % path if path else k) # For Root Valuess
for sub_k in d1[k]:
not_included_keys.append("%s.%s" % (k, sub_k))
continue
not_included_keys.append("%s.%s" % ("%s" % path if path else "", k))
return not_included_keys
现在假设我们有两个嵌套字典:a 和 b。
如果我想获得这两个词典的差异,我会 运行 以下内容。请注意,我没有将空列表指定为 not_included_keys
参数...
print("The following keys are included in A but not in B:")
diff_a_to_b = find_diff_keys(ini_dict_a, ini_dict_b)
pprint(diff_a_to_b)
print("")
print("The following keys are included in B but not in A:")
diff_b_to_a = find_diff_keys(ini_dict_b, ini_dict_a)
pprint(diff_b_to_a)
这个输出将是:
The following keys are included in A but not in B:
['FAIL.WEAREDOINGSOMETHING',
'FAIL.ehh',
'FAIL.dsa',
'FAIL.fds',
'FAIL.gd',
'FAIL.ewq',
'TESTVALUE',
'TESTVALUE.Name',
'TESTSUBSUB.TestValues2',
'TESTSUBSUB.TestValues2ltaHz']
The following keys are included in B but not in A:
['FAIL.WEAREDOINGSOMETHING',
'FAIL.ehh',
'FAIL.dsa',
'FAIL.fds',
'FAIL.gd',
'FAIL.ewq',
'TESTVALUE',
'TESTVALUE.Name',
'TESTSUBSUB.TestValues2',
'TESTSUBSUB.TestValues2ltaHz']
现在,如果我 运行 以空列表作为参数的函数:
diff_a_to_b = find_diff_keys(ini_dict_a, ini_dict_b, [])
diff_b_to_a = find_diff_keys(ini_dict_b, ini_dict_a, [])
输出将是:
The following keys are included in A but not in B:
['FAIL.WEAREDOINGSOMETHING',
'FAIL.ehh',
'FAIL.dsa',
'FAIL.fds',
'FAIL.gd',
'FAIL.ewq',
'TESTVALUE',
'TESTVALUE.Name',
'TESTSUBSUB.TestValues2',
'TESTSUBSUB.TestValues2ltaHz',
'TESTSUBSUB.TestValues2eltaHz']
The following keys are included in B but not in A:
['PointsConfig.130324',
'ResetAlarm.NotEnabledValue',
'ResetAlarm.SomeValue',
'PointsConfig.13032402.Mains.Some_small_difference']
有人能理解为什么在第一种方法中 python 只是复制旧列表,而在第二种方法中函数执行它应该做的事情吗?
不要使用可变对象作为默认参数。(列表、字典等)
改为这样做。
def append_to(element, to=None):
if to is None:
to = []
to.append(element)
return to
为什么?因为例如列表或字典是可变的,这意味着您在整个代码中编辑相同的引用。 python 在定义函数时创建列表,而不是在调用函数时创建列表,因为函数是 python.
中的第一个 class 公民
更多信息:https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments
我编写了一个函数来查找两个嵌套词典中的不同键。 answer.
给我很大的启发 def find_diff_keys(d1: dict, d2: dict, not_included_keys:list = [], path=""):
for k in d1:
if k in d2:
if type(d1[k]) is dict:
find_diff_keys(d1[k],d2[k],not_included_keys, "%s.%s" % (path, k) if path else k)
else:
if type(d1[k]) is dict:
not_included_keys.append("%s" % path if path else k) # For Root Valuess
for sub_k in d1[k]:
not_included_keys.append("%s.%s" % (k, sub_k))
continue
not_included_keys.append("%s.%s" % ("%s" % path if path else "", k))
return not_included_keys
现在假设我们有两个嵌套字典:a 和 b。
如果我想获得这两个词典的差异,我会 运行 以下内容。请注意,我没有将空列表指定为 not_included_keys
参数...
print("The following keys are included in A but not in B:")
diff_a_to_b = find_diff_keys(ini_dict_a, ini_dict_b)
pprint(diff_a_to_b)
print("")
print("The following keys are included in B but not in A:")
diff_b_to_a = find_diff_keys(ini_dict_b, ini_dict_a)
pprint(diff_b_to_a)
这个输出将是:
The following keys are included in A but not in B:
['FAIL.WEAREDOINGSOMETHING',
'FAIL.ehh',
'FAIL.dsa',
'FAIL.fds',
'FAIL.gd',
'FAIL.ewq',
'TESTVALUE',
'TESTVALUE.Name',
'TESTSUBSUB.TestValues2',
'TESTSUBSUB.TestValues2ltaHz']
The following keys are included in B but not in A:
['FAIL.WEAREDOINGSOMETHING',
'FAIL.ehh',
'FAIL.dsa',
'FAIL.fds',
'FAIL.gd',
'FAIL.ewq',
'TESTVALUE',
'TESTVALUE.Name',
'TESTSUBSUB.TestValues2',
'TESTSUBSUB.TestValues2ltaHz']
现在,如果我 运行 以空列表作为参数的函数:
diff_a_to_b = find_diff_keys(ini_dict_a, ini_dict_b, [])
diff_b_to_a = find_diff_keys(ini_dict_b, ini_dict_a, [])
输出将是:
The following keys are included in A but not in B:
['FAIL.WEAREDOINGSOMETHING',
'FAIL.ehh',
'FAIL.dsa',
'FAIL.fds',
'FAIL.gd',
'FAIL.ewq',
'TESTVALUE',
'TESTVALUE.Name',
'TESTSUBSUB.TestValues2',
'TESTSUBSUB.TestValues2ltaHz',
'TESTSUBSUB.TestValues2eltaHz']
The following keys are included in B but not in A:
['PointsConfig.130324',
'ResetAlarm.NotEnabledValue',
'ResetAlarm.SomeValue',
'PointsConfig.13032402.Mains.Some_small_difference']
有人能理解为什么在第一种方法中 python 只是复制旧列表,而在第二种方法中函数执行它应该做的事情吗?
不要使用可变对象作为默认参数。(列表、字典等)
改为这样做。
def append_to(element, to=None):
if to is None:
to = []
to.append(element)
return to
为什么?因为例如列表或字典是可变的,这意味着您在整个代码中编辑相同的引用。 python 在定义函数时创建列表,而不是在调用函数时创建列表,因为函数是 python.
中的第一个 class 公民更多信息:https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments