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)操作。这可能是许多用例所期望的行为,在这些用例中,您希望将操作应用于字典中的已过滤节点列表。