根据键值过滤python中的嵌套字典

时间:2012-05-04 17:35:54

标签: python dictionary

如何根据键值过滤python中的嵌套字典:

d = {'data': {'country': 'US', 'city': 'New York', 'state': None},
     'tags': ['US', 'New York'],
     'type': 'country_info',
     'growth_rate': None
     }

我想过滤此字典以消除NoneType值,因此产生的字典应为:

d = {'data': {'country': 'US', 'city': 'New York'},
     'tags': ['US', 'New York'],
     'type': 'country_info',
     }

此外,dict可以有多个嵌套级别。我想从字典中删除所有NoneType值。

2 个答案:

答案 0 :(得分:7)

您可以使用dict comprehension轻松递归地定义此内容。

def remove_keys_with_none_values(item):
    if not hasattr(item, 'items'):
        return item
    else:
        return {key: remove_keys_with_none_values(value) for key, value in item.items() if value is not None}

递归在Python中并没有太优化,但鉴于可能的嵌套数量相对较少,我不担心。

在我们跳跃之前看起来并不太Pythonic,我认为这是一个比捕捉异常更好的选择 - 因为它很可能在大多数时间内不会是dict(很可能我们有叶子比树枝多。)

另请注意,在Python 2.x中,您可能希望将iteritems()替换为items()

答案 1 :(得分:0)

我非常感谢@Lattyware的回答。它帮助我过滤掉嵌套对象并删除空值,无论其类型是dictlist还是str

以下是我提出的建议:

remove-keys-with-empty-values.py

# remove-keys-with-empty-values.py
from pprint import pprint

def remove_keys_with_empty_values(item):
  if hasattr(item, 'items'):
    return {key: remove_keys_with_empty_values(value) for key, value in item.items() if value==0 or value}
  elif isinstance(item, list):
    return [remove_keys_with_empty_values(value) for value in item if value==0 or value]
  else:
    return item

d = {
     'string': 'value',
     'integer': 10,
     'float': 0.5,
     'zero': 0,
     'empty_list': [],
     'empty_dict': {},
     'empty_string': '',
     'none': None,
    }

d['nested_dict'] = d.copy()
l = d.values()
d['nested_list'] = l

pprint({
  "DICT FILTERED": remove_keys_with_empty_values(d),
  "DICT ORIGINAL": d,
  "LIST FILTERED": remove_keys_with_empty_values(l),
  "LIST ORIGINAL": l,
})

执行

python remove-keys-with-empty-values.py
    {'DICT FILTERED': {'float': 0.5,
                       'integer': 10,
                       'nested_dict': {'float': 0.5,
                                       'integer': 10,
                                       'string': 'value',
                                       'zero': 0},
                       'nested_list': [0,
                                       'value',
                                       10,
                                       0.5,
                                       {'float': 0.5,
                                        'integer': 10,
                                        'string': 'value',
                                        'zero': 0}],
                       'string': 'value',
                       'zero': 0},
     'DICT ORIGINAL': {'empty_dict': {},
                       'empty_list': [],
                       'empty_string': '',
                       'float': 0.5,
                       'integer': 10,
                       'nested_dict': {'empty_dict': {},
                                       'empty_list': [],
                                       'empty_string': '',
                                       'float': 0.5,
                                       'integer': 10,
                                       'none': None,
                                       'string': 'value',
                                       'zero': 0},
                       'nested_list': [{},
                                       0,
                                       'value',
                                       None,
                                       [],
                                       10,
                                       0.5,
                                       '',
                                       {'empty_dict': {},
                                        'empty_list': [],
                                        'empty_string': '',
                                        'float': 0.5,
                                        'integer': 10,
                                        'none': None,
                                        'string': 'value',
                                        'zero': 0}],
                       'none': None,
                       'string': 'value',
                       'zero': 0},
     'LIST FILTERED': [0,
                       'value',
                       10,
                       0.5,
                       {'float': 0.5,
                        'integer': 10,
                        'string': 'value',
                        'zero': 0}],
     'LIST ORIGINAL': [{},
                       0,
                       'value',
                       None,
                       [],
                       10,
                       0.5,
                       '',
                       {'empty_dict': {},
                        'empty_list': [],
                        'empty_string': '',
                        'float': 0.5,
                        'integer': 10,
                        'none': None,
                        'string': 'value',
                        'zero': 0}]}