2

I have written a function designed to flatten a json. The function works recursively - if a key, value pair's value is not a json, the key,value pair is returned, otherwise, the function is called again on the value:

def flatten_json(j):
    for k, v in j.items():
        if isinstance(v, dict):
            flatten_json(v)
        else:
            yield (k,v)

flat_json = {x[0]: x[1] for x in flatten_json(j)}

The idea being that whenever the function yields a tuple, it is collected into the flat_json dict. As it stands, nested outputs are ignored - only the top level key, value pairs appear in flat_json.

2
  • do the nested keys need to be prefixed with their "parent" keys somehow? or just appear as-as in the flat_json as top level keys with the same name? Commented Nov 13, 2019 at 14:06
  • 1
    @Adam.Er8 No, they don't, so, for example: {'foo': 'bar, 'foo1': 'bar1', 'nest1': {'foo2': 'bar2'}} should return {'foo': 'bar, 'foo1': 'bar1', 'foo2': 'bar2'} Commented Nov 13, 2019 at 14:19

2 Answers 2

5

This is exactly what yield from is for :), to yield elements one by one from calling a generator from within a generator (whether that is a recursive call or not).

try:

def flatten_json(j):
    for k, v in j.items():
        if isinstance(v, dict):
            yield from flatten_json(v)
        else:
            yield (k,v)


j = {'foo': 'bar', 'foo1': 'bar1', 'nest1': {'foo2': 'bar2'}}
flat_json = {x[0]: x[1] for x in flatten_json(j)}
print(flat_json)

Output:

{'foo': 'bar', 'foo1': 'bar1', 'foo2': 'bar2'}

running example here: https://ideone.com/Z5aO9V

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

Comments

0

Yield it like the normal data:

yield (k, flatten_json(v))

Comments

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.