如何清除包含子字典的字典中的空键

0 投票
1 回答
956 浏览
提问于 2025-04-18 10:09

到目前为止,我在Python中有以下的正则表达式:

 (\"[^"]+":\s)({}|\[\]|null)(,?\s?)

我需要从一个字符串中匹配所有出现的“某个键”:[]、{}或null,但我需要排除“某个键”是“Note”的情况,示例字符串是:

test= {'merda 1': {},
         'merda 2': [1,2,3],
         1: """"só pra fude""",
         'Note': "foda-se",
         'Não reclama': [],
         'Tédio da nisso': OrderedDict({'Note': None, 1:2}),
         'None':None,
         'Quero $$$': (),
         'Note': [],
         12.2: None,
         666: OrderedDict(),
         'Fudeu': OrderedDict({1:None, 2:1, 3:2})
         }

string_json = json.dumps(test)

我的目的是过滤掉字典中的空叶子节点,但我需要保留其中的有序字典(OrderedDicts)。

解决方案:基于马丁的回答:

def clean_dict(dictobj):
    """ Clean any number of empty leafs of a dictionary
    """
    def del_empty_value(dictobj):
        """ Delete empty values recursively
        """
        for key, value in dictobj.items():
            if not (value or key == 'Note'):
                del dictobj[key]
            elif isinstance(value, dict):
                del_empty_value(value)
    from json import dumps
    initial_hash = len(dumps(dictobj))
    while True:
        del_empty_value(dictobj)
        new_hash = len(dumps(dictobj))
        if new_hash == initial_hash:
            break
        initial_hash = new_hash

1 个回答

2

为什么不让一个 JSON 解析器来帮你处理这些复杂的工作呢?

import json

s = '{"1": "\\"s\\u00f3 pra fude", "None": null, "Note": [], "N\\u00e3o reclama": [], "12.2": null, "666": {}, "merda 2": [1, 2, 3], "merda 1": {}, "T\\u00e9dio da nisso": {"Note": null}, "Fudeu": {"1": null, "2": 1, "3": 2}, "Quero $$$": []}'

d = json.loads(s)
result = dict((k, v) for k, v in d.iteritems() if not v or k == "Note")

最后一行的作用是过滤掉那些键值对,其中 bool(v) 不是 False(像 []{}None 都符合这个条件)或者键的值不是 "Note"。

结果是:

{u'12.2': None,
 u'666': {},
 u'None': None,
 u'Note': [],
 u'N\xe3o reclama': [],
 u'Quero $$$': [],
 u'merda 1': {}}

编辑:

由于问题已经更新,现在有了更好的答案:

 test= {'merda 1': {},
     'merda 2': [1,2,3],
     1: """"só pra fude""",
     'Note': "foda-se",
     'Não reclama': [],
     'Tédio da nisso': OrderedDict({'Note': None, 1:2}),
     'None':None,
     'Quero $$$': (),
     'Note': [],
     12.2: None,
     666: OrderedDict(),
     'Fudeu': OrderedDict({1:None, 2:1, 3:2})
     }

def delete_empty_value(test):
    for k, v in test.items():
        if not (v or type(k) is OrderedDict or k == 'Note'):
            del test[k]
        elif isinstance(v, dict):
            delete_empty_value(v)

这个新的过滤条件保留了任何键值对,前提是:

  1. 值不是 []{}None
  2. 值是 OrderedDict 的一个实例
  3. 键等于 "Note"

撰写回答