Проблемы, повторяющиеся через список JSON в Python?

у меня есть файл с данными 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"}
            }]
}

Я не могу понять, как правильно петля через 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

Я попытался пройти через них с:

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

но получите ошибку: TypeError: индексы списка должны быть целыми числами, а не dict

4 ответов


вы предполагаете, что i является индексом, но это словарь, используйте:

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

цитата по заявлениям:

оператор for в Python немного отличается от того, что вы можете использовать в C или Pascal. Вместо того, чтобы всегда повторять арифметическую прогрессию чисел (как в Pascal) или давать пользователю возможность определять как шаг итерации, так и условие остановки (как C),оператор Python для итераций над элементами любой последовательности (списка или строки), в том порядке, в котором они появляются в последовательности.


вы повторяете словарь не индексирует, поэтому вы должны либо использовать.

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

или

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

путаница в том, как словари и списки используются в итерации. Словарь будет перебирать его ключи (которые вы используете в качестве индексов для получения соответствующих значений)

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)

но поведение по умолчанию итерации по списку даст вам элементы вместо индексов:

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)

если вы хотите обобщить свою программу для обработки обоих типов одинаково, вы можете использовать одну из этих функций:

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))

таким образом, если вы, для например, позже изменил json для хранения результатов в dict, используя id в качестве ключей, программа все равно будет повторять его так же:

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

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

for json_data in data['Results']:
    for attribute, value in json_data.iteritems():
        print attribute, value # example usage