【问题标题】:Filter nested dictionary in python based on key values根据键值过滤python中的嵌套字典
【发布时间】:2012-05-14 06:39:24
【问题描述】:

如何在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 值。

【问题讨论】:

    标签: python dictionary


    【解决方案1】:

    您可以使用 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()

    【讨论】:

    • 我喜欢你的回答,这可能有点挑剔,但if value is not None 读起来更好。
    • @BrianHicks 已注意到并已修复,非常正确。
    • 我想如果我们想要更 Pythonic,你应该使用 if hasattr(item, 'items') 或者只是假设它被传递给字典。您可以按原样将[1, 2, None] 传递给该函数,然后返回带有无的相同项目。
    • @BrianHicks 我不认为打算从列表中删除None - 我认为这纯粹是为了删除值为None 的键。 hasattr(item, 'items') 可能也好一点,这是真的。
    • @Lattyware:为什么链接“字典理解”链接到有关列表理解的 YouTube 视频?因为够近?
    【解决方案2】:

    我非常感谢@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}]}
    

    【讨论】:

      猜你喜欢
      • 2015-05-17
      • 2017-06-07
      • 2019-06-26
      • 1970-01-01
      • 2010-11-15
      • 1970-01-01
      • 1970-01-01
      • 2021-09-04
      • 1970-01-01
      相关资源
      最近更新 更多