Issues iterating through JSON list in Python?

49,197

Solution 1

You are assuming that i is an index, but it is a dictionary, use:

for item in data["Results"]:
    print item["Name"]    

Quote from the for Statements:

The for statement in Python differs a bit from what you may be used to in C or Pascal. Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or giving the user the ability to define both the iteration step and halting condition (as C), Python’s for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence.

Solution 2

you are iterating through the dictionary not indexes so you should either use.

for item in data["Results"]:
    print item["Name"]    

or

for i in range(len(data["Results"])):
    print data["Results"][i]["Name"]

Solution 3

The confusion is in how dictionaries and lists are used in iteration. A dictionary will iterate over it's keys (which you use as indices to get corresponding values)

x = {"a":3,  "b":4,  "c":5}
for key in x:   #same thing as using x.keys()
   print(key,x[key]) 

for value in x.values():
    print(value)      #this is better if the keys are irrelevant     

for key,value in x.items(): #this gives you both
    print(key,value)

but the default behaviour of iterating over a list will give you the elements instead of the indices:

y = [1,2,3,4]
for i in range(len(y)):  #iterate over the indices
    print(i,y[i])

for item in y:
    print(item)  #doesn't keep track of indices

for i,item in enumerate(y): #this gives you both
    print(i,item)

If you want to generalize your program to handle both types the same way you could use one of these functions:

def indices(obj):
    if isinstance(obj,dict):
        return obj.keys()
    elif isinstance(obj,list):
        return range(len(obj))
    else:
        raise TypeError("expected dict or list, got %r"%type(obj))

def values(obj):
    if isinstance(obj,dict):
        return obj.values()
    elif isinstance(obj,list):
        return obj
    else:
        raise TypeError("expected dict or list, got %r"%type(obj))

def enum(obj):
    if isinstance(obj,dict):
        return obj.items()
    elif isinstance(obj,list):
        return enumerate(obj)
    else:
        raise TypeError("expected dict or list, got %r"%type(obj))

this way if you, for example, later changed the json to store the results in a dict using the id as keys the program would still iterate through it the same way:

#data = <LOAD JSON>
for item in values(data["Results"]):
    print(item["name"])

#or
for i in indices(data["Results"]):
    print(data["Results"][i]["name"])

Solution 4

for json_data in data['Results']:
    for attribute, value in json_data.iteritems():
        print attribute, value # example usage
Share:
49,197
Bajan
Author by

Bajan

Updated on August 01, 2022

Comments

  • Bajan
    Bajan almost 2 years

    I have a file with JSON data in it, like so:

    {
        "Results": [
                {"Id": "001",
                "Name": "Bob",
                "Items": {
                    "Cars": "1",
                    "Books": "3",
                    "Phones": "1"}
                },
    
                {"Id": "002",
                "Name": "Tom",
                "Items": {
                    "Cars": "1",
                    "Books": "3",
                    "Phones": "1"}
                },
    
                {"Id": "003",
                "Name": "Sally",
                "Items": {
                    "Cars": "1",
                    "Books": "3",
                    "Phones": "1"}
                }]
    }
    

    I can not figure out how to properly loop through the JSON. I would like to loop through the data and get a Name with the Cars for each member in the dataset. How can I accomplish this?

    import json
    
    with open('data.json') as data_file:
        data = json.load(data_file)
    
    print data["Results"][0]["Name"] # Gives me a name for the first entry
    print data["Results"][0]["Items"]["Cars"] # Gives me the number of cars for the first entry
    

    I have tried looping through them with:

    for i in data["Results"]:
    print data["Results"][i]["Name"]    
    

    But recieve an error: TypeError: list indices must be integers, not dict

  • Bajan
    Bajan over 8 years
    That makes sense now, thanks for your quick reply!! I am still unsure how I would loop through the sub-object for each one though?
  • alecxe
    alecxe over 8 years
    @Bajan sure, assuming you mean the Items dictionary: for key, value in item["Items"].iteritems():. Please see the related topics: docs.python.org/2/tutorial/datastructures.html#dictionaries, stackoverflow.com/questions/3294889/….
  • Bajan
    Bajan over 8 years
    You are quick! I got it done by using this: for item in data["Results"]: print item["Items"]["Cars"] Which would be the recommended method?