make a dict/json from string with duplicate keys Python

Question:

I have a string that could be parsed as a JSON or dict object. My string variable looks like this :

my_string_variable = """{
                        "a":1,
                        "b":{
                             "b1":1,
                             "b2":2
                         },  
                        "b": { 
                            "b1":3, 
                            "b2":2,
                            "b4":8
                         } 
                       }"""

When I do json.loads(my_string_variable), I have a dict but only the second value of the key "b" is kept, which is normal because a dict can’t contain duplicate keys.

What would be the best way to have some sort of defaultdict like this :

result = {
    "a": 1,
    "b": [{"b1": 1, "b2": 2}, {"b1": 3, "b2": 2, "b4": 8}],
}

I have already looked for similar questions but they all deal with dicts or lists as an input and then create defaultdicts to handle the duplicate keys.

In my case I have a string variable and I would want to know if there is a simple way to achieve this.

Asked By: Samiella

||

Answers:

something like the following can be done.

import json

def join_duplicate_keys(ordered_pairs):
    d = {}
    for k, v in ordered_pairs:
        if k in d:
           if type(d[k]) == list:
               d[k].append(v)
           else:
               newlist = []
               newlist.append(d[k])
               newlist.append(v)
               d[k] = newlist
        else:
           d[k] = v
    return d

raw_post_data = '{"a":1, "b":{"b1":1,"b2":2}, "b": { "b1":3, "b2":2,"b4":8} }'
newdict = json.loads(raw_post_data, object_pairs_hook=join_duplicate_keys)
print (newdict)

Please note that above code depends on value type, if type(d[k]) == list. So if original string itself gives a list then there could be some error handling required to make the code robust.

Answered By: Kevin
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.