Exclude empty/null values from JSON serialization
def del_none(d): """ Delete keys with the value ``None`` in a dictionary, recursively. This alters the input so you may wish to ``copy`` the dict first. """ # For Python 3, write `list(d.items())`; `d.items()` won’t work # For Python 2, write `d.items()`; `d.iteritems()` won’t work for key, value in list(d.items()): if value is None: del d[key] elif isinstance(value, dict): del_none(value) return d # For convenience
Sample usage:
>>> mydict = {'dict1': {'key1': 'value1', 'key2': None}}>>> print(del_none(mydict.copy())){'dict1': {'key1': 'value1'}}
Then you can feed that to 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'}}>>>
I don't like using del
in general, changing the existing dictionary can have subtle effects depending on how they are created. Creating new dictionaries with None
removed prevents all side effect.
My Python3 version of this has the benefit of not changing the input, as well as recursion into dictionaries nested in lists:
def clean_nones(value): """ Recursively remove all None values from dictionaries and lists, and returns the result as a new dictionary or list. """ if isinstance(value, list): return [clean_nones(x) for x in value if x is not None] elif isinstance(value, dict): return { key: clean_nones(val) for key, val in value.items() if val is not None } else: return value
For example:
a = { "a": None, "b": "notNone", "c": ["hello", None, "goodbye"], "d": [ { "a": "notNone", "b": None, "c": ["hello", None, "goodbye"], }, { "a": "notNone", "b": None, "c": ["hello", None, "goodbye"], } ]}print(clean_nones(a))
results in this:
{ 'b': 'notNone', 'c': ['hello', 'goodbye'], 'd': [ { 'a': 'notNone', 'c': ['hello', 'goodbye'] }, { 'a': 'notNone', 'c': ['hello', 'goodbye'] } ]}