Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在深度嵌套字典中设置值_Python_Python 3.x - Fatal编程技术网

Python 在深度嵌套字典中设置值

Python 在深度嵌套字典中设置值,python,python-3.x,Python,Python 3.x,所以我有一本字典: dct = { 'a': { 'b': { 'c': 'lowercase' } } } 我正在尝试将“小写”字符串大写 当然,这是可行的: dct['a']['b']['c'] = dct['a']['b']['c'].upper() 但是,我想看看是否有更好的方法来更新嵌套值。键“a”、“b”、“c”很短很简单,但当它进入更深层次的嵌套字典时,读长键名并将其分成不同的行会有点让人不知所措

所以我有一本字典:

dct = {
     'a': {
         'b': {
             'c': 'lowercase'
         }
     }
}
我正在尝试将“小写”字符串大写

当然,这是可行的:

dct['a']['b']['c'] = dct['a']['b']['c'].upper()
但是,我想看看是否有更好的方法来更新嵌套值。键“a”、“b”、“c”很短很简单,但当它进入更深层次的嵌套字典时,读长键名并将其分成不同的行会有点让人不知所措


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

请尝试这个。它的递归函数

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))
分两步进行:(1)获取要在其中设置值的词典,(2)执行更新

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

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

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

如果您希望对字典中的一个或多个项应用操作,并仅在某些节点中筛选以执行该操作,这是一种很好的方法

>>> 
>>> 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节点的点分隔路径的正则表达式

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

不要使用
path
参数-这是递归函数的“内部使用”

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))
此函数将访问所有节点,这是一个
O(N)
操作。如果使用正确,这应具有足够的性能。此函数将为您访问所有节点并应用任何任意操作,因此无需将其放入任何迭代字典项的循环中。

如果要使用
“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
来捕捉错误路径

你所说的“更好”是什么意思。这是从嵌套字典访问值的方法。你可以做的是给变量一个不同的名字,就像现在一样,它是隐藏的内置dict。使用一些循环使它更容易。您还可以创建获取
'a.b.c'
的函数,并将其拆分,然后使用
循环
获取/设置值。目标是在给定键序列的情况下执行一次更新(即
'a','b','c'
)-不搜索整个结构并更新密钥的每次出现。抱歉,我不知道。但是它不是与
dct['a']['b']['c']=dct['a']['b']['c']]相同吗?我遗漏了什么吗?@Ch3steR如果没有相同的结果,那么这将是一个错误的答案。不同的是,长序列的键不必写两次。我从来没有说过这个答案给出了错误的结果;)你认为Pythic中的哪一个。我个人认为,无论哪种方式都是好代码。可以说,这违反了任何一种方式。取而代之的是什么取决于键和嵌套结构是固定的还是动态的,以及数据是由您自己的代码生成的还是来自某个API。但问题不在于如何做到这一点。我已经更新了它,以处理使用表达式搜索复杂dict树的键和值的各种方法,然后对它们执行指定的操作。这可以在非常特定的位置查找和修改单个节点,或者更普遍地应用于多个节点。顺便说一句,此解决方案实际上回答了标题“在深度嵌套字典中设置值”的问题。从谷歌登陆这里的人可能会发现这个答案很有用。现在它确实有用,但它仍然通过搜索整个嵌套结构来实现,当你只想更改一个值并且知道访问它的键时,这是不必要的。那么Kaya呢。这仍然是一个O(N)操作。这可能是许多用例所期望的行为,在这些用例中,您希望将操作应用于字典中的已过滤节点列表。