【问题标题】:Recursive dictionary modification in pythonpython中的递归字典修改
【发布时间】:2014-01-12 02:38:09
【问题描述】:

翻这本词典最简单的方法是什么:

{'item':{'w':{'c':1, 'd':2}, 'x':120, 'y':240, 'z':{'a':100, 'b':200}}}

进入这个:

{'item':{'y':240, 'z':{'b':200}}}

仅考虑到您需要变量 y 和 b 同时保持字典的结构?项目的大小或数量或字典的深度应该无关紧要,因为我正在使用的字典可以是 2 到 5 层深。

编辑:我为之前的类型道歉,并澄清一下,我得到了一个字符串数组(例如 ['y', 'b']),我需要在字典中找到它们,然后只保留 'y'和 'b' 以及任何其他键以保持原始字典的结构,在这种情况下,它将是 'z'

可以在here 找到更好的示例,我需要芯片组型号、VRAM 和分辨率。

关于评论,输入将是作为起始字典的上述链接以及作为保留列表的 ['chipset model', 'vram', 'resolution'] 数组。它应该返回这个:

{'Graphics/Displays':{'NVIDIA GeForce 7300 GT':{'Chipset Model':'NVIDIA GeForce 7300 GT', 'Displays':{'Resolution':'1440 x 900 @ 75 Hz'}, 'VRAM (Total)':'256 Mb'}}

【问题讨论】:

  • 我需要 y 和 b,但是 z 必须留下来保持原始字典的结构。我不只想要 y 和 b 的值,而是需要结构和值
  • 写一个输入和一个想要的输出。并编写非期望输出的示例。因为我在这里迷路了。

标签: python python-2.7 recursion dictionary


【解决方案1】:

假设您要分配给超级词典元素的词典是foo,您可以这样做:

my_dictionary['keys']['to']['subdict']=foo

关于你的编辑——你需要删除除特定列表中的所有键之外的所有键——这个函数应该可以解决问题:

def drop_keys(recursive_dict,keep_list):
    key_list=recursive_dict.keys()
    for key in key_list:
        if(type(recursive_dict[key]) is dict):
            drop_keys(recursive_dict[key], keep_list)
        elif(key not in keep_list):
            del recursive_dict[key]

【讨论】:

  • 我不相信我之前说得不够清楚,抱歉,但是考虑到我需要搜索的值数组同时保持原始字典的结构,这将不起作用
  • 在将 elif(recursive_dict[key] 更改为 elif(key.lower() 后效果很好,谢谢!
【解决方案2】:

这样的?

d = {'item': {'w': {'c': 1, 'd': 2}, 'x': 120, 'y': 240, 'z': {'a': 100, 'b': 200}}}
l = ['y', 'z']
def do_dict(d, l):
    return {k: v for k, v in d['item'].items() if k in l}

【讨论】:

  • 它更接近,这将适用于只有两个级别的字典,但不适用于任何级别的字典,我添加了一个更好的示例
【解决方案3】:

这是我得出的递归解决方案,最终与@Dan 发布的类似:

def recursive_del(d,keep):
    for k in d.copy():
        if type(d[k]) == dict:
            recursive_del(d[k],keep)
            if len(d[k]) == 0: #all keys were deleted, clean up empty dict
                del d[k]
        elif k not in keep:
            del d[k]

演示:

>>> keepset = {'y','b'}
>>> a = {'item':{'w':{'c':1, 'd':2}, 'x':120, 'y':240, 'z':{'a':100, 'b':200}}}
>>> recursive_del(a,keepset)
>>> a
{'item': {'z': {'b': 200}, 'y': 240}}

我认为他错过的唯一一件事是您有时需要清理已删除所有密钥的字典;即,如果没有这种调整,您最终会在示例输出中得到一个残留的 'w':{}

【讨论】:

  • 是的,这是我添加的内容之一,Dan 先回答了,所以我会给他功劳。谢谢两位的帮助!
【解决方案4】:

使用你的第二个例子我做了这样的事情,它不是很漂亮,但它应该很容易扩展。如果你的树开始变大,你可以定义一些规则来解析字典。

这里的每条规则实际上几乎都是“当我处于哪个状态时我应该做什么”。

def rule2(key, value):
    if key == 'VRAM (Total)':
        return (key, value)
    elif key == 'Chipset Model':
        return (key, value)

def rule1(key, value):
    if key == "Graphics/Displays":
        if isinstance(value, dict):
            return (key, recursive_checker(value, rule1))
        else:
            return (key, value)
    else:
        return (key, recursive_checker(value, rule2))

def recursive_checker(dat, rule):

    def inner(item):
        key = item[0]
        value = item[1]

        return rule(key, value)

    return dict(filter(lambda x: x!= None, map(inner, dat.items())))

# Important bits    
print recursive_checker(data, rule1)

在您的情况下,由于状态不多,因此不值得这样做,但如果您有多张卡并且您不一定知道应该遍历哪个键,但只知道您想要某些键树。此方法可用于轻松搜索树。它可以应用于很多事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    • 2017-04-06
    • 2019-07-30
    • 2022-01-14
    • 2022-10-15
    • 2021-04-10
    相关资源
    最近更新 更多