Python nested dictionary – remove "" and data with extra spaces but keep None values

Question:

I have a dictionary and would like to keep None values but remove values with "" and also values of any combination of " "’s

I have the following dictionary:

{'UserName': '',
 'Location': [{'City': '',
   'Country': 'Japan',
   'Address 1': '    ',
   'Address 2': ' '}],
 'PhoneNumber': [{'Number': '123-456-7890', 'ContactTimes': '', 'PreferredLanguage': None}],
 'EmailAddress': [{'Email': '[email protected]', 'Subscribed': None}],
 'FriendCount': [{'SumAsString': 'xndiofa!#$*9'}]
}

Expected result:

{
 'Location': [{
   'Country': 'Japan',
}],
 'PhoneNumber': [{'Number': '123-456-7890', 'PreferredLanguage': None}],
 'EmailAddress': [{'Email': '[email protected]', 'Subscribed': None}],
 'FriendCount': [{'SumAsString': 'xndiofa!#$*9'}]
}

I have this function and its partially working but I cant figure out how to remove key’s with the extra spaces.

def delete_junk(_dict):

    for key, value in list(_dict.items()):
        if isinstance(value, dict):
            delete_junk(value)
        elif value == '':
            del _dict[key]
        elif isinstance(value, list):
            for v_i in value:
                if isinstance(v_i, dict):
                    delete_junk(v_i)

    return _dict
Asked By: aero8991

||

Answers:

Your approach was sound; I also think defining a function using recursion is how I would approach the problem. I would use .isspace() to help.

def delete_junk(d):
    """
    Recursively removes empty strings or strings consisting only of whitespaces
    from the input dictionary and its nested dictionaries and lists.
    """
    if isinstance(d, dict):
        return {k: remove_empty_strings(v) for k, v in d.items() if v != "" and not str(v).isspace()}
    elif isinstance(d, list):
        return [remove_empty_strings(v) for v in d if v != "" and not str(v).isspace()]
    else:
        return d


i = {'UserName': '',
 'Location': [{'City': '',
   'Country': 'Japan',
   'Address 1': '    ',
   'Address 2': ' '}],
 'PhoneNumber': [{'Number': '123-456-7890', 'ContactTimes': '', 'PreferredLanguage': None}],
 'EmailAddress': [{'Email': '[email protected]', 'Subscribed': None}],
 'FriendCount': [{'SumAsString': 'xndiofa!#$*9'}]
}

output_dict = delete_junk(i)

print(output_dict)
# Output: {'Location': [{'Country': 'Japan'}],
#          'PhoneNumber': [{'Number': '123-456-7890', 'PreferredLanguage': None}],
#          'EmailAddress': [{'Email': '[email protected]', 'Subscribed': None}],
#          'FriendCount': [{'SumAsString': 'xndiofa!#$*9'}]}
Answered By: artemis

With single dict comprehension implying recursive calls:

def delete_junk(d):
    return {k: [delete_junk(i) for i in v] if isinstance(v, list) else v
            for k, v in d.items() 
            if not isinstance(v, str) or v.strip()}

print(delete_junk(dct))

{'EmailAddress': [{'Email': '[email protected]', 'Subscribed': None}],
 'FriendCount': [{'SumAsString': 'xndiofa!#$*9'}],
 'Location': [{'Country': 'Japan'}],
 'PhoneNumber': [{'Number': '123-456-7890', 'PreferredLanguage': None}]}
Answered By: RomanPerekhrest
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.