我在我的一个项目中使用了kendoUI Grid。我使用他们的api检索了一段数据,发现它在我的json / dictionary中添加了一些“不需要的”数据。将json传递回我的Pyramid后端后,我需要删除这些键。问题是,字典可以是任何深度,我不提前知道深度。
示例:
product = {
id: "PR_12"
name: "Blue shirt",
description: "Flowery shirt for boys above 2 years old",
_event: {<some unwanted data here>},
length: <some unwanted data>,
items: [{_event: {<some rubbish data>}, length: <more rubbish>, price: 23.30, quantity: 34, color: "Red", size: "Large"}, {_event: {<some more rubbish data>}, length: <even more rubbish>, price: 34.50, quantity: 20, color: "Blue", size: "Large"} ....]
}
我想特别删除两个键:“_ event”&amp; “长度”。我尝试编写一个递归函数来删除数据,但我似乎无法做到正确。有人可以帮忙吗?
这就是我所拥有的:
def remove_specific_key(the_dict, rubbish):
for key in the_dict:
if key == rubbish:
the_dict.pop(key)
else:
# check for rubbish in sub dict
if isinstance(the_dict[key], dict):
remove_specific_key(the_dict[key], rubbish)
# check for existence of rubbish in lists
elif isinstance(the_dict[key], list):
for item in the_dict[key]:
if item == rubbish:
the_dict[key].remove(item)
return the_dict
答案 0 :(得分:5)
如果允许remove_specific_key
(重命名为remove_keys
)接受任何对象作为其第一个参数,那么您可以简化代码:
def remove_keys(obj, rubbish):
if isinstance(obj, dict):
obj = {
key: remove_keys(value, rubbish)
for key, value in obj.iteritems()
if key not in rubbish}
elif isinstance(obj, list):
obj = [remove_keys(item, rubbish)
for item in obj
if item not in rubbish]
return obj
由于您希望删除多个密钥,因此您可以将rubbish
设置为一个而不是一个特定密钥。
使用上面的代码,您可以使用
product = remove_keys(product, set(['_event', 'length']))
编辑:remove_key
使用Python {2}中引入的dict comprehension。对于旧版本的Python,等效的是
obj = dict((key, remove_keys(value, rubbish))
for key, value in obj.iteritems()
if key not in rubbish)
答案 1 :(得分:4)
在迭代错误时修改dict,这是不必要的,因为你确切知道你要找的是什么键。此外,您的dicts列表未正确处理:
def remove_specific_key(the_dict, rubbish):
if rubbish in the_dict:
del the_dict[rubbish]
for key, value in the_dict.items():
# check for rubbish in sub dict
if isinstance(value, dict):
remove_specific_key(value, rubbish)
# check for existence of rubbish in lists
elif isinstance(value, list):
for item in value:
if isinstance(item, dict):
remove_specific_key(item, rubbish)
答案 2 :(得分:1)
在迭代时不能删除dict或list,所以用测试函数替换迭代器。
def remove_specific_key(the_dict, rubbish):
if the_dict.has_key(rubbish):
the_dict.pop(rubbish)
else:
for key in the_dict:
if isinstance(the_dict[key], dict):
remove_specific_key(the_dict[key], rubbish)
elif isinstance(the_dict[key], list):
if the_dict[key].count(rubbish):
the_dict[key].remove(rubbish)
return the_dict
d = {"a": {"aa": "foobar"}}
remove_specific_key(d, "aa")
print d
d = {"a": ["aa", "foobar"]}
remove_specific_key(d, "aa")
print d