3

I was wondering if there was a way to use json.loads in order to automatically convert an empty string in something else, such as None.

For example, given:

data = json.loads('{"foo":"5", "bar":""}')

I would like to have:

data = {"foo":"5", "bar":None}

Instead of:

data = {"foo":"5", "bar":""}
2
  • 2
    Why? Both are falsey so you could catch them Commented Aug 26, 2018 at 13:22
  • You could try some thing like .replace("\"\"", "None") on the string before loading it into json. Commented Aug 26, 2018 at 13:41

3 Answers 3

4

You can use a dictionary comprehension:

data = json.loads('{"foo":"5", "bar":""}')
res = {k: v if v != '' else None for k, v in data.items()}

{'foo': '5', 'bar': None}

This will only deal with the first level of a nested dictionary. You can use a recursive function to deal with the more generalised nested dictionary case:

def updater(d, inval, outval):
    for k, v in d.items():
        if isinstance(v, dict):
            updater(d[k], inval, outval)
        else:
            if v == '':
                d[k] = None
    return d

data = json.loads('{"foo":"5", "bar":"", "nested": {"test": "", "test2": "5"}}')

res = updater(data, '', None)

{'foo': '5', 'bar': None,
 'nested': {'test': None, 'test2': '5'}}
Sign up to request clarification or add additional context in comments.

Comments

3

You can also accomplish this with the json.loads object_hook parameter. For example:

import json
import six


def empty_string2none(obj):
    for k, v in six.iteritems(obj):
        if v == '':
            obj[k] = None
    return obj


print(json.loads('{"foo":"5", "bar":"", "hello": {"world": ""}}',
                 object_hook=empty_string2none))

This will print

{'foo': '5', 'bar': None, 'hello': {'world': None}}

This way, you don't need additional recursion.

Comments

0

I did some trial and error and it is impossible to parse None into a String using json.loads() you will have to use json.loads() with json.dumps() like I do in this example:

import json

data = json.loads('{"foo":"5", "bar":"%r"}' %(None))
data2 = json.loads(json.dumps({'foo': 5, 'bar': None}))


if data2['bar'] is None:
    print('worked')
    print(data['bar'])
else:
    print('did not work')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.