在深层嵌套字典中设置值

时间:2020-03-02 18:13:28

标签: python python-3.x

所以我有一本字典:

dct = {
     'a': {
         'b': {
             'c': 'lowercase'
         }
     }
}

我正在尝试将小写的字符串大写。

当然可以,

dct['a']['b']['c'] = dct['a']['b']['c'].upper()

但是,我试图查看是否有更好的方法来更新嵌套值。键“ a”,“ b”,“ c”简短而简单,但是当涉及到更深的嵌套字典时,读取长键名并将其分成不同的行有点有点不知所措。

我一直在研究glom,但这更多的是从深度嵌套的字典中获取值。

4 个答案:

答案 0 :(得分:1)

如果要使用"a.b.c",则将其拆分并使用循环获取元素

dct = {'a': {'b': {'c': 'lowercase'} } }

path = 'a.b.c'

keys = path.split('.')
last = keys[-1]

element = dct

for key in keys[:-1]:
    element = element[key]

element[last] = element[last].upper()

print(dct)

编辑:您甚至可以创建获取字典,路径和函数的函数,这些函数可以获取值并返回新值

def apply(dct, path, function):
    keys = path.split('.')
    last = keys[-1]

    element = dct

    for key in keys[:-1]:
        element = element[key]

    element[last] = function(element[last])

# --- main ---

dct = {'a': {'b': {'c': 'lowercase'} } }

apply(dct, 'a.b.c', str.upper)

print(dct)  # {'a': {'b': {'c': 'LOWERCASE'}}}

apply(dct, 'a.b.c', str.capitalize)

print(dct)  # {'a': {'b': {'c': 'Lowercase'}}}

apply(dct, 'a.b.c', len)

print(dct)  # {'a': {'b': {'c': 9}}}

顺便说一句:需要try/except才能找到错误的路径

答案 1 :(得分:0)

请尝试这个。它的递归功能。

data_dict = {
    'a': {
        'b': {
            'c': 'lowercase'
        }
    }
}

def update_dict(key, data_dict):
    if isinstance(data_dict, dict):
        for dict_key, dict_value in data_dict.items():
            if dict_key==key:
                data_dict[key]= data_dict[key].upper()
            else:
                update_dict(key, dict_value)

    return data_dict

print(update_dict('c', data_dict))

答案 2 :(得分:0)

分两个步骤进行:(1)获取要在其中设置值的字典,(2)执行更新。

d = dct['a']['b']
d['c'] = d['c'].upper()

答案 3 :(得分:0)

将操作应用于过滤后的字典项集-使用简单的正则表达式选择项。

如果您想以一种与xpath相似的方式(但使用regex)对与正则表达式匹配的值执行任何类型的操作,则这是一种方法。

如果要对字典中的一个或多个项目应用操作并仅在某些节点上进行过滤以执行该操作,这是一种很好的方法。

>>> 
>>> def dict_operation(d, regex, operation, path=''):
...     """
...     Apply 'operation' to dictionary items whose keys match the
...     'regex' expression.
...     """
...     for key, val in d.items():
...         if type(val) is str:
...             cur_path = '.'.join([path, str(key), val])
...             if re.match(regex, cur_path):
...                 d[key] = operation(key, val)
...         elif type(val) is dict:
...             dict_operation(val, regex, operation, '.'.join([path, str(key)]))
...   

此示例搜索字典树,以查找其中包含单词“ case” 并且也是“ c” 键的子代的任何终端字符串值。

>>> 
>>> d = {'a': {'b': {'c': 'lowercase'}}}
>>> 
>>> dict_operation(d, r".*\.c\..*case", lambda k, v: v.upper())
>>> 
>>> d
{'a': {'b': {'c': 'LOWERCASE'}}}
>>> 

该表达式将应用于点.分隔的路径。此路径包含搜索的键和最终值,例如:a.b.c.lowercase

regex参数指定一个正则表达式,该正则表达式将应用于当前dict节点的点分隔路径。

operation参数指定要在词典中找到的终端字符串节点上执行的操作。

请勿使用path参数-递归函数将其用于“内部使用”。

此功能将访问所有节点,这是一个O(N)操作。如果正确使用,则应具有足够的性能。此函数将为您访问所有节点并应用任何任意操作,因此不必将其置于对字典项进行迭代的任何循环中。