Python 从JSON序列化中排除空/空值

Python 从JSON序列化中排除空/空值,python,json,simplejson,Python,Json,Simplejson,我正在使用Python和simplejson将多个嵌套字典序列化为JSON 有没有办法自动排除空/空值 例如,序列化以下内容: { "dict1" : { "key1" : "value1", "key2" : None } } 到 将Jackson与Java一起使用时,可以使用Inclusion.NON_NULL来执行此操作。有一个simplejson等价物吗 def excludeNone(d): for k in list(d):

我正在使用Python和simplejson将多个嵌套字典序列化为JSON

有没有办法自动排除空/空值

例如,序列化以下内容:

 {
     "dict1" : {
     "key1" : "value1",
     "key2" : None
     }
 }

将Jackson与Java一起使用时,可以使用
Inclusion.NON_NULL
来执行此操作。有一个simplejson等价物吗

def excludeNone(d):
    for k in list(d):
        if k in d:
            if type(d[k]) == dict:
                excludeNone(d[k])
            if not d[k]:
                del d[k]
示例用法:

>>> mydict = {'dict1': {'key1': 'value1', 'key2': None}}
>>> print(del_none(mydict.copy()))
{'dict1': {'key1': 'value1'}}
然后您可以将其输入到
json

>>> def cleandict(d):
...     if not isinstance(d, dict):
...         return d
...     return dict((k,cleandict(v)) for k,v in d.iteritems() if v is not None)
... 
>>> mydict = dict(dict1=dict(key1='value1', key2=None))
>>> print cleandict(mydict)
{'dict1': {'key1': 'value1'}}
>>> 

一般来说,我不喜欢使用
del
,更改现有词典可能会产生微妙的影响,具体取决于它们的创建方式。在删除
None
的情况下创建新词典可以防止所有副作用。

My Python3版本的优点是不更改输入,并且可以递归到嵌套在列表中的词典中:

def clean_nones(值):
"""
递归地从字典和列表中删除所有None值,并返回
结果将显示为新词典或列表。
"""
如果isinstance(值,列表):
return[如果x不是None,则x的值为clean_nones(x)]
elif isinstance(值,dict):
返回{
钥匙:清洁(val)
对于键,value.items()中的val
如果val不是None
}
其他:
返回值
例如:

a={
“a”:无,
“b”:“无”,
“c”:[“你好”,无,“再见”],
“d”:[
{
“a”:“无”,
“b”:无,
“c”:[“你好”,无,“再见”],
},
{
“a”:“无”,
“b”:无,
“c”:[“你好”,无,“再见”],
}
]
}
印刷品(清洁(a))
结果如下:

{
    'b': 'notNone',
    'c': ['hello', 'goodbye'],
    'd': [
        {
            'a': 'notNone',
            'c': ['hello', 'goodbye']
        },
        {
            'a': 'notNone',
            'c': ['hello', 'goodbye']
        }
    ]
}
这对我很有用:

当字典有dict/list/tuple值时

例如,它是我的对象:

dict_obj = {
    'inline_keyboard': [
        [
            {'text': '0-0', 'url': None, 'login_url': None, 'callback_data': '0-0', 'switch_inline_query': None},
            {'text': '0-1', 'url': None, 'login_url': None, 'callback_data': '0-1', 'switch_inline_query': None}
        ],
        [
            {'text': '1-0', 'url': None, 'login_url': None, 'callback_data': '1-0', 'switch_inline_query': None},
            {'text': '1-1', 'url': None, 'login_url': None, 'callback_data': '1-1', 'switch_inline_query': None}
        ],
        [
            {'text': '2-0', 'url': None, 'login_url': None, 'callback_data': '2-0', 'switch_inline_query': None}
        ]
    ]
}
我写了这个函数:

def delete_none_values(obj):
    if isinstance(obj, dict):
        for k, v in list(obj.items()):
            if v is None:
                del obj[k]
            elif isinstance(v, dict):
                delete_none_values(v)
            elif isinstance(v, (list, tuple)):
                for _ in v:
                    delete_none_values(_)
    elif isinstance(obj, (list, tuple)):
        for _ in obj:
            delete_none_values(_)
    return obj
然后当使用此功能时:

from json import dumps

print(
    dumps(
        delete_none_values(dict_obj.copy()),
        indent=2
    )
)
输出为:

{
  "inline_keyboard": [
    [
      {"text": "0-0", "callback_data": "0-0"},
      {"text": "0-1", "callback_data": "0-1"}
    ],
    [
      {"text": "1-0", "callback_data": "1-0"},
      {"text": "1-1", "callback_data": "1-1"}
    ],
    [
      {"text": "2-0", "callback_data": "2-0"}
    ]
  ]
}

如果d[k]不是None,使用
会更安全,而不是
如果不是d[k]
——否则空字符串和0值也将从输出中排除。Em。。。。这会产生
运行时错误:使用Python3.5
def del_none(d)在迭代过程中更改了字典的大小递归删除字典中值为``None``且字符串为空的键。这不会改变输入,而是复制字典。儿童词典也被复制。不复制其他对象。“”“rez=d.copy(),用于键,d.items()中的值:如果值为None或value=”“:del-rez[key]elif-isinstance(value,dict):rez[key]=del_-None(value)return rez
@AleksandrPanzin:我已经用Python 2的注释更新了针对Python 3的代码。这是七年前编写的!但是,我将其保留为一个就地修改。请注意……这些答案都不会递归到列表中。列表中出现的字典将继续使用任何空值进行序列化。这仍然是一个问题不是python标准库的一部分吗?我很惊讶!python 3.x中的
d.items()
,这应该是公认的答案,因为问题是关于json的,json允许列表中的对象!
from json import dumps

print(
    dumps(
        delete_none_values(dict_obj.copy()),
        indent=2
    )
)
{
  "inline_keyboard": [
    [
      {"text": "0-0", "callback_data": "0-0"},
      {"text": "0-1", "callback_data": "0-1"}
    ],
    [
      {"text": "1-0", "callback_data": "1-0"},
      {"text": "1-1", "callback_data": "1-1"}
    ],
    [
      {"text": "2-0", "callback_data": "2-0"}
    ]
  ]
}