Python3弹出嵌套Json键给出字符串路径



用例

我需要根据传递给我的脚本的可变长度字符串Pop((一个嵌套的JSON键。

示例

给定字典{'IP': {'key1': 'val1', 'key2': 'val2'}},如果我的脚本作为IP.key1传递路径,如何从字典中弹出key1

请注意,这需要在给定任意数量的键的情况下工作。

到目前为止,我已经在Stack上找到了这个代码片段,它可以用来查找密钥,但我无法真正删除密钥:

data = {'IP': {'key1': 'val1', 'key2': 'val2'}}
lst = ['IP', 'key1'] # Convert the string of keys to an array
def get(d,l):
if len(l)==1: return d[l[0]]
return get(d[l[0]],l[1:])
print(get(data, lst))

此外,我在一个受限的环境中工作,所以使用任何利基库都不是一种选择。

我觉得可能有一种简单的方法可以调整它来弹出完整的路径,但递归让我头疼。有什么想法吗?

编辑

Filip Müller的答案似乎对我有效。但他没有提供太多上下文,所以我正在更新它,以展示一个更复杂的数据集和我使用的基于Filip答案的函数

data = {'IP': {'key1': {'key3': {'key4': 'val4', 'key5': 'val5'}}, 'key2': 'val2'}}
lst = ['IP', 'key1', 'key3', 'key4']

def popKey(d, l):
current_level = d
for key in l[:-1]:
print(key)
current_level = current_level[key]
print(current_level)
current_level.pop(l[-1])
return d

print(popKey(data, lst))
data = {'IP': {'key1': 'val1', 'key2': 'val2'}}
lst = ['IP', 'key1']
current_level = data
for key in lst[:-1]:
current_level = current_level[key]
current_level.pop(lst[-1])

解释

我将使用您提供的更复杂的示例来解释这是如何工作的。任务的第一部分是找到实际上应该删除关键字的字典。

{
'IP': {
'key1': {
'key3': {
'key4': 'val4',
'key5': 'val5'
}
},
'key2': 'val2'
}
}
path = ['IP', 'key1', 'key3', 'key4']

在本例中,为了删除关键字'key4',我们首先需要找到包含该关键字的字典,即'key3'下的字典。如果我们在一个变量中有这个特定的字典,比如d,我们可以直接调用d.pop('key4')

'key3': {
'key4': 'val4',
'key5': 'val5'
}

该字典的路径为data['IP']['key1']['key3']。该算法不是直接这样进行,而是从根字典开始,并随着for循环的每次迭代而深入一个级别。因此,在第一次迭代之后,current_level就是data['IP']。在下一个之后,它变为data['IP']['key1']。(因为current_level已经是data['IP'],所以current_level = current_level['key1']确实与data['IP']['key1']相同。(

重复此过程,直到找到所需的词典为止。这意味着要对列表中指定路径的每个元素执行此操作,而不是最后一个,因为最后一个不再是字典,而是我们搜索的字典中的键。(lst[:1]是Python表示lst中除最后一个元素外的所有元素的方式。(

最后,我们简单地从它实际所属的字典中弹出必要的关键字(列表中的最后一个元素,换句话说,lst[-1](,即算法在第一步中找到的关键字。

也许是这样的:

def get(d, lst):
for i in range(len(lst) - 1):
d = d[lst[i]]
d.pop(lst[-1])
return data

print(get(data, lst))

输出:

{'IP': {'key2': 'val2'}}

看看这个!

data = {'IP': {'key1': {'key3':'val1','key4':'val2'}, 'key2': 'val2'}}
lst = ['IP', 'key1','key4']
temp = data
for i in range(len(lst) - 1):
d = temp[lst[i]]
temp = d
d.pop(lst[-1])
print(data)

输出:

{'IP': {'key1': {'key3': 'val1'}, 'key2': 'val2'}}

对于您的用例来说,这是一个人性化的代码,我将['key1','key2']封装在一个数组中,这样它更有意义,但如果您不想封装它,您可以相应地更改代码。

data = {'IP': {'key1': 'val1', 'key2': 'val2'}}
lst = ['IP', ['key1','key2']] # Convert the string of keys to an array
def remove_key_from_dict(data,list):
for nested_key in list[1]:
parent_key = list[0]
del data[parent_key][nested_key]

print(data)    
remove_key_from_dict(data, lst)

输出:

{'IP': {}}

相关内容

  • 没有找到相关文章

最新更新