Object_hook in json module doesn't seem to work as expected

Viewed 97

I have:

def decoder(o):
  return o.get("fruits")


array = '{"fruits": [{"apple": "red"}, {"banana": "yellow"}, "orange"]}'
data  = json.loads(array, object_hook=decoder)
print(data)

This is returning [None, None, 'orange'].

However, if I do something like below without using object_hook

n = json.loads(array)
print(n.get("fruits"))

This returns [{'apple': 'red'}, {'banana': 'yellow'}, 'orange'] as desired.

How can I use object_hook to return [{'apple': 'red'}, {'banana': 'yellow'}, 'orange'] instead of [None, None, 'orange']? What part of my code is causing it to return None?

2 Answers

The return value of object_hook will be used instead of the dict

Notice: return value of object_hook would replace all dict object in your json string

# the reason you get None: 

# 1 inner dict {"apple": "red"} apply "object_hook" 
# 2 return o.get("fruits") --> None


You can try with below codes for your reference:

import json


def decoder(o):
    if o.get("fruits"):
        return o["fruits"]
    return o


array = '{"fruits": [{"apple": "red"}, {"banana": "yellow"}, "orange"]}'
data = json.loads(array, object_hook=decoder)
print(data)

A good way to understand what happens is to print o:

{'apple': 'red'}
{'banana': 'yellow'}
{'fruits': [None, None, 'orange']}
[None, None, 'orange']

Now it seems the mystery is solved. As for how to solve it with I don't think it should be used like that. You can of course keep the code you currently have and then filter the list for all element that are not None like:

result_list = [x if x is not None for x in result_list]

Where result_list stores the values from json.loads

Related