theomega
theomega

Reputation: 32041

Json in Python: Receive/Check duplicate key error

The json module of python acts a little of the specification when having duplicate keys in a map:

import json
>>> json.loads('{"a": "First", "a": "Second"}')
{u'a': u'Second'}

I know that this behaviour is specified in the documentation:

The RFC specifies that the names within a JSON object should be unique, but does not specify how repeated names in JSON objects should be handled. By default, this module does not raise an exception; instead, it ignores all but the last name-value pair for a given name:

For my current project, I absolutely need to make sure that no duplicate keys are present in the file and receive an error/exception if this is the case? How can this be accomplished?

I'm still stuck on Python 2.7, so a solution which also works with older versions would help me most.

Upvotes: 8

Views: 3055

Answers (2)

Shrikant Nadiger
Shrikant Nadiger

Reputation: 1

The below code will take any json that has repeated keys and put them into an array. for example takes this json string '''{"a":"hi","a":"bye"}''' and gives {"a":['hi','bye']} as output

import json
def dupe_checking_hook(pairs):
    result = dict()
    for key,val in pairs:
        if key in result:
            if(type(result[key]) == dict):
                temp = []
                temp.append(result[key])
                temp.append(val)
                result[key] = temp
            else:
                result[key].append(val)
        else:
            result[key] = val
    return result

decoder = json.JSONDecoder(object_pairs_hook=dupe_checking_hook)
#it will not raise error
some_json = decoder.decode('''{"a":"hi","a":"bye"}''')

Upvotes: 0

Amber
Amber

Reputation: 526753

Well, you could try using the JSONDecoder class and specifying a custom object_pairs_hook, which will receive the duplicates before they would get deduped.

import json

def dupe_checking_hook(pairs):
    result = dict()
    for key,val in pairs:
        if key in result:
            raise KeyError("Duplicate key specified: %s" % key)
        result[key] = val
    return result

decoder = json.JSONDecoder(object_pairs_hook=dupe_checking_hook)

# Raises a KeyError
some_json = decoder.decode('''{"a":"hi","a":"bye"}''')

# works
some_json = decoder.decode('''{"a":"hi","b":"bye"}''')

Upvotes: 13

Related Questions