在Python中迭代JSON列表的问题?

时间:2022-09-04 20:19:02

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

我有一个包含JSON数据的文件,如下所示:

{
    "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?

我无法弄清楚如何正确循环JSON。我想循环遍历数据,并为数据集中的每个成员获取一个带有汽车的名称。我怎么能做到这一点?

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

但是收到一个错误:TypeError:list indices必须是整数,而不是dict

3 个解决方案

#1


15  

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.

Python中的for语句与您在C或Pascal中使用的语句略有不同。而不是总是迭代数字的算术级数(如在Pascal中),或者让用户能够定义迭代步骤和暂停条件(如C),Python的for语句迭代任何序列的项目(列表或一个字符串),按照它们出现在序列中的顺序。

#2


6  

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"]

#3


2  

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:

这种方式,例如,如果您稍后更改了json以使用id作为键将结果存储在dict中,程序仍将以相同的方式迭代它:

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

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

#1


15  

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.

Python中的for语句与您在C或Pascal中使用的语句略有不同。而不是总是迭代数字的算术级数(如在Pascal中),或者让用户能够定义迭代步骤和暂停条件(如C),Python的for语句迭代任何序列的项目(列表或一个字符串),按照它们出现在序列中的顺序。

#2


6  

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"]

#3


2  

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:

这种方式,例如,如果您稍后更改了json以使用id作为键将结果存储在dict中,程序仍将以相同的方式迭代它:

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

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