python - 递归搜索嵌套字典并将函数应用于搜索键:值对

时间:2018-04-18 10:15:24

标签: python oop dictionary recursion nested

我已经看到了这个问题的答案Finding a key recursively in a dictionary。但是,它没有给我预期的结果。问题是它一旦找到它就停止寻找给定的密钥。这意味着如果字典中有其他键的实例,那么这些将被忽略。

假设我的字典看起来如下:

nested_dico = {
     'columns': {
                'background_color': 'A5300F',
                'font': {'bold': True, 'color': 'FFFFFF', 'size': 15}},
     'index': {
                'background_color': 'E1CDCC'},
     'master': {
                'align': 'center',
                'background_color': 'FFFFFF',
                'font': {'color': '000000', 'name': 'arial', 'size': 16},
                'vertical_anchor': 'middle'}}

所需的行为是函数能够将给定的转换应用于与键匹配的字典中的所有元素。

例如,当运行converter(nested_dico, 'size', lambda x: x*2)时,我希望converter返回相同的字典,其中所有大小值乘以2.我需要的实际实现是将所有颜色值从Hex转换为RGB代码。

奖励指出,如果你能让它适用于部分字符串。例如:converter(nested_dico, 'color', RGB())将更改background_colorcolor值!

理想地寻找优雅的pythonic解决方案。

2 个答案:

答案 0 :(得分:3)

nested_dico = {
     'columns': {
                'background_color': 'A5300F',
                'font': {'bold': True, 'color': 'FFFFFF', 'size': 15}},
     'index': {
                'background_color': 'E1CDCC'},
     'master': {
                'align': 'center',
                'background_color': 'FFFFFF',
                'font': {'color': '000000', 'name': 'arial', 'size': 16},
                'vertical_anchor': 'middle'}}



def seletive_map(origin,matcher,mapper,current_keys=[]):
    result = {}
    for k,v in origin.items():
        if matcher(current_keys + [k]):
            result[k] = mapper(v)
        elif hasattr(v,'items'):
            result[k] = seletive_map(v,matcher,mapper,current_keys + [k])
        else:
            result[k] = v
    return result

result = seletive_map(nested_dico,lambda keys: keys[-1] == "size",lambda x : x*2)
#result = seletive_map(nested_dico,lambda keys: "color" in keys[-1],RGB)


print result

答案 1 :(得分:2)

是否要将转换函数应用于与字典中的模式匹配的任何嵌套键?

d = {"color": 1, 'child': {"color": 2}}

def transform(d, p, t):
    for each in d:
        if isinstance(d[each], dict):
            transform(d[each], p, t)
        if each == p: 
            d[each] = t(d[each])

transform(d, "color", lambda x: x+1)

如果你想概括"你如何确定模式是否匹配",那么你可以将逻辑作为这样的函数传递:

d = {"color": 1, 'child': {"background-color": 2}}

def transform(d, p, t):
    for each in d:
        if type(d[each]) == dict:
            transform(d[each], p, t)
        if p(each): 
            d[each] = t(d[each])

transform(d, lambda x: 'color' in x, lambda x: x+1)

参数p被称为predicate函数。您可以使用'color' in x来调用它来处理部分字符串,例如。