当前位置: 首页 > 知识库问答 >
问题:

用另一个字典的值替换嵌套字典的键(其中两个dict的键相等),键的值可以是dict的列表

拓拔奇
2023-03-14
dict1 = {"key1":{"key3":"value1","key2":"value2","key4":{"key5":"value3","key6":{"key7":"value4","key8":{"key9":"value5","key10":"value6","key55":"value7"}},"key11":{"key12":"value8","key13":"value9"},"key14":[{"key15":"value10","key16":"value11","key17":"value12"},{"key15":"value13","key16":"value14","key17":"value15"}]}}}

dict2 = {"key1":"ab","key2":"bc","key3":"cd","key4":"de","key5":"ef","key6":"fg","key7":"gh","key8":"hi","key9":"ij","key10":"jk","key55":"kl","key11":"lm","key12":"mn","key13":"no","key14":"op","key15":"pq","key16":"qr","key17":"qs"}
def walk(dict1, dict2):
    output = {}
    for key, value in dict1.iteritems():

        if isinstance(value, dict):
            output[dict2[key]] = walk(value, dict2)
        elif isinstance(value, list):
            output[dict2[key]] = walk_list(value, dict2)
        else:
            output[dict2[key]] = value
    return output

def walk_list(sublist, dict2):
    output = []
    for i in sublist:

        if isinstance(i, dict):
            output = walk(i, dict2)
        elif isinstance(value, list):
            output = walk_list(i, dict2)
        else:
            output.append((key, value))
    return output

output = walk(dict1, dict2)
output = json.dumps(output)
print output
 {"ab": {"de": {"lm": {"mn": "value8", "no": "value9"}, "ef": "value3", "fg": {"hi": {"ij": "value5", "jk": "value6", "kl": "value7"}, "gh": "value4"}, "op": {"pq": "value13", "qs": "value15", "qr": "value14"}}, "bc": "value2", "cd": "value1"}}

预期产出为

 {"ab":{"cd":"value1","bc":"value2","de":{"ef":"value3","fg":{"gh":"value4","hi":{"ij":"value5","jk":"value6","kl":"value7"}},"lm":{"mn":"value8","no":"value9"},"op":[{"pq":"value10","qr":"value11","qs":"value12"},{"pq":"value13","qr":"value14","qs":"value15"}]}}}

请修复我的代码。

共有1个答案

茅秦斩
2023-03-14

非常简单的解决方案,很早就执行递归步骤,因此具有非常简单的逻辑

def translateKeys (obj, keyNames):
    if isinstance(obj, dict):
        return {keyNames.get(k, k): translateKeys(v, keyNames) for k, v in obj.items()}
    elif isinstance(obj, list):
        return [translateKeys(v, keyNames) for v in obj]
    else:
        return obj

它不是期望某个类型,而是接受任何东西(字典、列表或其他任何东西),并处理它的项,为每个值调用它自己。这避免了必须遍历obj本身并检查循环中每个项的值。

用于示例数据:

>>> dict1 = {"key1":{"key3":"value1","key2":"value2","key4":{"key5":"value3","key6":{"key7":"value4","key8":{"key9":"value5","key10":"value6","key55":"value7"}},"key11":{"key12":"value8","key13":"value9"},"key14":[{"key15":"value10","key16":"value11","key17":"value12"},{"key15":"value13","key16":"value14","key17":"value15"}]}}}
>>> dict2 = {"key1":"ab","key2":"bc","key3":"cd","key4":"de","key5":"ef","key6":"fg","key7":"gh","key8":"hi","key9":"ij","key10":"jk","key55":"kl","key11":"lm","key12":"mn","key13":"no","key14":"op","key15":"pq","key16":"qr","key17":"qs"}
>>> expected =  {"ab":{"cd":"value1","bc":"value2","de":{"ef":"value3","fg":{"gh":"value4","hi":{"ij":"value5","jk":"value6","kl":"value7"}},"lm":{"mn":"value8","no":"value9"},"op":[{"pq":"value10","qr":"value11","qs":"value12"},{"pq":"value13","qr":"value14","qs":"value15"}]}}}
>>> result = translateKeys(dict1, dict2)
>>> result
{'ab': {'de': {'fg': {'gh': 'value4', 'hi': {'ij': 'value5', 'jk': 'value6', 'kl': 'value7'}}, 'op': [{'qr': 'value11', 'pq': 'value10', 'qs': 'value12'}, {'qr': 'value14', 'pq': 'value13', 'qs': 'value15'}], 'ef': 'value3', 'lm': {'no': 'value9', 'mn': 'value8'}}, 'cd': 'value1', 'bc': 'value2'}}
>>> result == expected
True
>>> result = translateKeys(dict1, dict2)
>>> invertedKeyNames = {v: k for k, v in dict2.items()}
>>> original = translateKeys(result, invertedKeyNames)
>>> original == dict1
True
 类似资料:
  • 问题内容: 您将如何基于列表的值来修改/创建嵌套dict的dict中的键/值,其中列表的最后一项是dict的值,而其余项会返回到dict中的键?这将是列表: 仅在诸如解析命令行参数之类的情况下,这才是问题。显然,在脚本中修改/创建此值将非常容易。 这将是字典的嵌套字典: 我猜在这种情况下,将需要诸如递归函数或列表理解之类的东西。 另外,如果中的项目会重新引用不存在的字典中的键,则应创建它们。 问题

  • 问题内容: 我有这段代码: 当我运行该代码时,出现以下错误: TypeError:无法散列的类型:’dict’ 该错误的原因是什么,我该怎么解决? 问题答案: 从错误中,我推断这是一个字典(请参阅下面的repro)。字典不能被散列,因此不能用作另一个字典的键(或本身就是这个键!)。 您可能意思是或。如果这两种解决方案都不起作用,那么在有关什么类型和是什么以及它们包含什么的更多上下文中,我们将能够为

  • 问题内容: 我有这段代码: 当我运行该代码时,出现以下错误: TypeError:无法散列的类型:’dict’ 该错误的原因是什么,我该怎么办才能解决? 问题答案: 从错误中,我推断出它是字典(请参阅下面的repro)。字典不能被散列,因此不能用作另一个字典的键(或本身就是该键!)。 您可能意思是或。如果这两种解决方案都不起作用,则可以通过更多上下文了解什么是类型以及它们包含什么,我们将能够为您提

  • 问题内容: 在Django模板中,有没有办法从其中有空格的键中获取值?例如,如果我有一个像这样的字典: 如何在模板中引用该值?伪语法可能是: 问题答案: 没有干净的方法使用内置标签来执行此操作。尝试做类似的事情: 将引发解析错误。 你可以在字典中进行for循环(但丑陋/效率低下): 自定义标签可能更干净: 并在模板中使用它,如下所示: 或者,也许尝试重组你的字典,使其具有“更易于使用”的键。

  • 问题内容: 在键路径的帮助下从嵌套字典中获取值,这是: 该方法的输入参数是点分隔的关键路径,从关键路径=“ app.Garden.Flowers.white Flower”需要打印’Jasmine’。到目前为止,我的代码: 问题答案: 很接近。您需要(就像您在评论中一样)以递归方式遍历主JSON对象。您可以通过存储最外面的键/值的结果,然后使用它来获取下一个键/值等来完成操作,直到您脱离路径为止。

  • 问题内容: 我有以下字典 我想获取字典列表中每个字典值“ KA20”和“ KA23”的键“ tmst”的总和。 您能对此提出建议吗? 问题答案: 您可以使用: 请注意,要正常工作,必须按分组键进行排序: