2

In my JSON file I have sequence of same-named records

"ability_upgrades":{
    "ability":5155,
    "time":1226
},
"ability_upgrades":{
    "ability":5155,
    "time":1426
},
"ability_upgrades":{
    "ability":5155,
    "time":1497
},
"ability_upgrades":{
    "ability":5157,
    "time":1543
},

If I will use json.loads it will save only last of that records.
What I have to do if I want a list of ability_upgrades?

3
  • 3
    Are you in any position to change the file format? Because this JSON is horribly broken, and broken JSON is as much of a bug as any TypeError or kernel panic. It's not clear whether you're asking about how to format your JSON properly or how to force your code to read it despite the errors. Commented May 23, 2015 at 0:21
  • @user2357112 Yes, I know. It is not real JSON ofc. It is output of dota2 game log. I just make it JSON-like with some regex manipulations to easy-parse. Commented May 23, 2015 at 0:41
  • 1
    Then why not generate something valid, like a list of objects instead of an object with the same key over and over, or even a stream of separate objects? Commented May 23, 2015 at 1:08

1 Answer 1

5

The documentation says a parameter called object_pairs_hook in json.loads can be used for handling duplicated records:

>>> json.loads(s, object_pairs_hook=(lambda x:  x))
[(u'ability_upgrades', [(u'ability', 5155), (u'time', 1226)]), (u'ability_upgrades', [(u'ability', 5155), (u'time', 1426)]), (u'ability_upgrades', [(u'ability', 5155), (u'time', 1497)]), (u'ability_upgrades', [(u'ability', 5157), (u'time', 1543)])]

How that function is defined is totally depending on what you want it to be. In the example above, since that hook gets as parameters a list of pairs, the identity function simply gives the list back.

E.g., if you define:

def collectAbilityUpgrades(s):
    d = {}
    for k, v in s:
        if k not in d:
            d[k] = []
        d[k].append(v)
    return d

Then:

>>> json.loads(s, object_pairs_hook=collectAbilityUpgrades)
{u'ability_upgrades': [{u'ability': [5155], u'time': [1226]}, {u'ability': [5155], u'time': [1426]}, {u'ability': [5155], u'time': [1497]}, {u'ability': [5157], u'time': [1543]}]}

Which probably is similar to what you want.

Sign up to request clarification or add additional context in comments.

1 Comment

Reading the fine documentation...gosh what a novel concept! Good implementation of a suitable hook, too. +1

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.