gpt4 book ai didi

python - 我如何递归地遍历 2 个字典,并根据另一个字典修改原始字典?

转载 作者:行者123 更新时间:2023-12-04 03:52:57 24 4
gpt4 key购买 nike

我正在尝试遍历一个字典(它有很多字符串、字典、字典列表),并将它与另一个字典进行比较。

这是一个例子:

data = {
"topic": "Seniors' Health Care Freedom Act of 2007",
"foo": "bar",
"last_update": "2011-08-29T20:47:44Z",
"organisations": [
{
"organization_id": "22973",
"name": "National Health Federation",
"bar": "baz"
},
{
"organization_id": "27059",
"name": "A Christian Perspective on Health Issues"
},
]}

validate = {
"topic": None,
"last_update": "next_update",
"organisations": [
{
"organization_id": None,
"name": None
}
]
}

本质上,如果该项目存在于“数据”中,但当前不在“验证”中,则应从数据中删除它。

所以在这种情况下,我希望从数据字典中删除 data["foo"] 和 data["organisations"][x]["bar"]。

此外,如果验证中的键有一个字符串值并且不是“无”,我想更新数据中的键名,即“last_update”应该变成“next_update”。

我不确定在 Python 中执行此操作的好方法,我当前的版本删除了“foo”,但我正在努力尝试删除像 organisations[x][bar] 这样的嵌套键。

这是我目前的尝试:

def func1(data, validate, parent = None):
for k, v in sorted(data.items()):
if not parent:
if k not in validate:
data.pop(k, None)

if isinstance(v, dict):
func1(v, validate)
elif isinstance(v, list):
for val in v:
func1(val, validate, parent = k)

func1(data, validate)

我尝试使用类似这样的方法来比较键,但认为如果数据有额外的键(似乎删除了错误的键),它就不能很好地工作,因为字典是未排序的,所以对我没有用:

for (k, v), (k2, v2) in zip(sorted(data.items()), sorted(validate.items())):

我读过类似的帖子,例如 How to recursively remove certain keys from a multi-dimensional(depth not known) python dictionary? ,但这似乎使用平面集进行过滤,因此它没有考虑 key 在字典中的位置,这对我来说很重要 - 因为“last_update”可以出现在我需要保留它的其他列表中。

最佳答案

这是一个简单的递归函数。好吧,它曾经很简单;然后我添加了大量的检查,现在它是一个 if 森林。

def validate_the_data(data, validate):
for key in list(data.keys()):
if key not in validate:
del data[key]
elif validate[key] is not None:
if isinstance(data[key], dict):
validate_the_data(data[key], validate[key])
elif isinstance(data[key], list):
for subdata, subvalidate in zip(data[key], validate[key]):
if isinstance(subdata, dict) and isinstance(subvalidate, dict):
validate_the_data(subdata, subvalidate)
else:
data[key] = validate[key]

工作原理:如果 data[key] 是字典并且 key 有效,那么我们要检查 中的键code>data[key]validate[key] 中的键。所以我们进行递归调用,但不是将 validate 放入递归调用中,而是放入 validate[key]。同样,如果 data[key] 是一个列表。

假设如果 data 中的列表之一包含不是字典的元素,或者如果 data[key] 是字典,当 validate[key] 存在但不是字典或 None 时,或者当 validate[key] 时 data[key] 是列表 存在但不是列表或无。

关于 if 森林的重要说明: if/else/if/elif/else 的顺序很重要。特别是,我们只在没有列表的情况下执行 data[key] = validate[key]。如果 validate[key] 是一个列表,那么 data[key] = validate[key] 将导致 data[key] 成为 相同的列表,而不是列表的副本,这肯定不是您想要的。

关于 list(data.keys()) 的重要说明:我使用迭代 for key in list(data.keys()): 而不是 for key in data:for key, value in data:。通常这不是遍历 dict 的首选方式。但是我们在 for 循环中使用 del 来从字典中删除值,这会干扰迭代。所以我们需要在删除任何元素之前获取键列表,然后使用该列表进行迭代。

关于python - 我如何递归地遍历 2 个字典,并根据另一个字典修改原始字典?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64175854/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com