我试图从嵌套词典中删除非值。我的第一次努力工作正常,但不幸的是,指向现在空的dicts的键仍然存在。
所以,如果我这样做:
pass1 = stripper(my_dict)
return stripper(pass1)
这有效,但我认为可能有更优雅的嵌套解决方案吗?
def stripper(self, data):
if isinstance(data, dict):
d = ({k: stripper(v) for k, v in data.items()
if v not in [u'', None]})
if d:
return d
else:
return data
编辑:
失败的示例,下面的dict返回为{'foo': 'bar', 'bar': None}
:
{
'foo': 'bar',
'bar': {
'foo': None,
'one': None
}
}
答案 0 :(得分:2)
字典理解当然简洁,但如果你把它扩展出来,解决方案就会变得更加明显:
def stripper(self, data):
new_data = {}
for k, v in data.items():
if isinstance(v, dict):
v = stripper(v)
if not v in (u'', None, {}):
new_data[k] = v
return new_data
答案 1 :(得分:0)
将接受的答案扩展为包括可能是列表元素的对象:
def strip_empties_from_list(data):
new_data = []
for v in data:
if isinstance(v, dict):
v = strip_empties_from_dict(v)
elif isinstance(v, list):
v = strip_empties_from_list(v)
if v not in (None, str(), list(), dict(),):
new_data.append(v)
return new_data
def strip_empties_from_dict(data):
new_data = {}
for k, v in data.items():
if isinstance(v, dict):
v = strip_empties_from_dict(v)
elif isinstance(v, list):
v = strip_empties_from_list(v)
if v not in (None, str(), list(), dict(),):
new_data[k] = v
return new_data
要使用:
data = {
'None': None,
'empty_list': [],
'empty_dict': {},
'empty_string': '',
'list_with_empties': ['', {}, [], None, {'more_empties': '', 'and_even_more': [''], 'one_thing_i_care_about': 'hi'}]
}
stripped_data = strip_empties_from_dict(data)
print(stripped_data)
答案 2 :(得分:0)
@Oliver 的答案是正确的,但是进行一些边缘情况检查不会有什么坏处,给您:(由于队列已满,无法编辑 Oliver 的答案)
def dictionary_stripper(data):
new_data = {}
# Only iterate if the given dict is not None
if data:
for k, v in data.items():
if isinstance(v, dict):
v = CampaignAdminUtils.dictionary_stripper(v)
# ideally it should be not in, second you can also add a empty list if required
if v not in ("", None, {}, []):
new_data[k] = v
# Only if you want the root dict to be None if empty
if new_data == {}:
return None
return new_data
return None