-1

I know how to parse a JSON knowing the key value, but now I'd like to get the key values from a JSON that it's not mine, so I can know the key names, for instance I have this JSON

[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  },
  {
    "id": 2,
    "name": "Ervin Howell",
    "username": "Antonette",
    "email": "Shanna@melissa.tv",
    "address": {
      "street": "Victor Plains",
      "suite": "Suite 879",
      "city": "Wisokyburgh",
      "zipcode": "90566-7771",
      "geo": {
        "lat": "-43.9509",
        "lng": "-34.4618"
      }
    },
    "phone": "010-692-6593 x09125",
    "website": "anastasia.net",
    "company": {
      "name": "Deckow-Crist",
      "catchPhrase": "Proactive didactic contingency",
      "bs": "synergize scalable supply-chains"
    }
  },
  ...
 ]

So from now I have this :

with open('users.json') as f:
    data = json.load(f)

Where I can see all the JSON loaded if I print data, so my question is, how do I print all of the keys and nested objects without knowing the name?

My goal is having something like id name username email address that contains street, suite, city, zipcode, geo that contains lat, long, etc..

StuartDTO
  • 783
  • 7
  • 26
  • 72
  • Ultimately, I think this will be of little use. At some point you're going to have to examine the JSON yourself to understand what you want. If you get all of the keys and drop the values, you'll still need to maintain the nested structure in order to know how to actually get at them... which means reading it anyway – roganjosh Sep 19 '18 at 20:16
  • 1
    What do you mean? – StuartDTO Sep 19 '18 at 20:18
  • Hmm ok, so you just want to know how to iterate the data? All you have is a list with nested dictionaries inside (as soon as you do `data = json.load(f)` it's not JSON anymore). – roganjosh Sep 19 '18 at 20:19
  • Yes I know, and I'm trying to get the keys from that list – StuartDTO Sep 19 '18 at 20:21
  • it’s just a regular dict once you load it as you do – mad.meesh Sep 19 '18 at 20:23
  • And then how can I load to avoid this? – StuartDTO Sep 19 '18 at 20:24
  • Read it in as a string. Then it would be almost completely impossible to work with. The fact that JSON translates to python lists and dicts so easily is a _blessing_ – roganjosh Sep 19 '18 at 20:27
  • It is a list of dict. you can get keys of dict from `.keys()` and values from `.values()` – mad_ Sep 19 '18 at 20:40
  • There are many objects in JSON format in the sample in your question. These will be treated as dictionaries in Python, so the question becomes from level do you want them—or are you asking for _all_ of them, at every level? If it's the latter, how do you expect to be able parse things with it? – martineau Sep 19 '18 at 21:15

2 Answers2

7

Here's a recursive generator that will scan through a nested list / dictionary structure, like you get from loading JSON into Python. It shows you the sequence of dictionary keys and list indices associated with every value.

I've modified your data slightly to illustrate how it handles lists nested inside dicts.

data = [
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    },
    "other": ["This", "is", "a list"]
  },
  {
    "id": 2,
    "name": "Ervin Howell",
    "username": "Antonette",
    "email": "Shanna@melissa.tv",
    "address": {
      "street": "Victor Plains",
      "suite": "Suite 879",
      "city": "Wisokyburgh",
      "zipcode": "90566-7771",
      "geo": {
        "lat": "-43.9509",
        "lng": "-34.4618"
      }
    },
    "phone": "010-692-6593 x09125",
    "website": "anastasia.net",
    "company": {
      "name": "Deckow-Crist",
      "catchPhrase": "Proactive didactic contingency",
      "bs": "synergize scalable supply-chains"
    },
    "other": ["This", "is", "another list"]
  },
]    

def show_indices(obj, indices):
    for k, v in obj.items() if isinstance(obj, dict) else enumerate(obj):
        if isinstance(v, (dict, list)):
            yield from show_indices(v, indices + [k])
        else:
            yield indices + [k], v

for keys, v in show_indices(data, []):
    print(keys, v)

output

[0, 'id'] 1
[0, 'name'] Leanne Graham
[0, 'username'] Bret
[0, 'email'] Sincere@april.biz
[0, 'address', 'street'] Kulas Light
[0, 'address', 'suite'] Apt. 556
[0, 'address', 'city'] Gwenborough
[0, 'address', 'zipcode'] 92998-3874
[0, 'address', 'geo', 'lat'] -37.3159
[0, 'address', 'geo', 'lng'] 81.1496
[0, 'phone'] 1-770-736-8031 x56442
[0, 'website'] hildegard.org
[0, 'company', 'name'] Romaguera-Crona
[0, 'company', 'catchPhrase'] Multi-layered client-server neural-net
[0, 'company', 'bs'] harness real-time e-markets
[0, 'other', 0] This
[0, 'other', 1] is
[0, 'other', 2] a list
[1, 'id'] 2
[1, 'name'] Ervin Howell
[1, 'username'] Antonette
[1, 'email'] Shanna@melissa.tv
[1, 'address', 'street'] Victor Plains
[1, 'address', 'suite'] Suite 879
[1, 'address', 'city'] Wisokyburgh
[1, 'address', 'zipcode'] 90566-7771
[1, 'address', 'geo', 'lat'] -43.9509
[1, 'address', 'geo', 'lng'] -34.4618
[1, 'phone'] 010-692-6593 x09125
[1, 'website'] anastasia.net
[1, 'company', 'name'] Deckow-Crist
[1, 'company', 'catchPhrase'] Proactive didactic contingency
[1, 'company', 'bs'] synergize scalable supply-chains
[1, 'other', 0] This
[1, 'other', 1] is
[1, 'other', 2] another list

You can use these lists to access any item, eg

keys = [1, 'company', 'catchPhrase']
obj = data
for k in keys:
    obj = obj[k]
print(obj)

output

Proactive didactic contingency

Or if you want to modify an item:

keys = [1, 'company', 'catchPhrase']
obj = data
for k in keys[:-1]:
    obj = obj[k]
obj[keys[-1]] = "some new thing"
print(data[1]['company'])

output

{'name': 'Deckow-Crist', 'catchPhrase': 'some new thing', 'bs': 'synergize scalable supply-chains'}
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
-1

Try someting like this

for d in data:
    for key in d.keys():
        print(d[key])