web-dev-qa-db-fra.com

Des problèmes d'itération via la liste JSON en Python?

J'ai un fichier contenant des données JSON, comme ceci:

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

Je ne peux pas comprendre comment boucler correctement le JSON. Je voudrais parcourir les données et obtenir un nom avec les voitures pour chaque membre de l'ensemble de données. Comment puis-je accomplir cela?

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

J'ai essayé de les parcourir avec:

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

Mais recevez une erreur: TypeError: les index de liste doivent être des entiers, pas dict

13
Bajan

Vous supposez que i est un index, mais c'est un dictionnaire, utilisez:

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

Citation du pour les déclarations :

L'instruction for dans Python diffère un peu de ce à quoi vous pouvez être habitué en C ou Pascal. Plutôt que de toujours itérer sur une progression arithmétique des nombres (comme en Pascal), ou donner à l'utilisateur le possibilité de définir à la fois l'étape d'itération et la condition d'arrêt (comme C), L'instruction for de Python itère sur les éléments de n'importe quelle séquence (une liste ou une chaîne), dans l'ordre dans lequel ils apparaissent dans le séquence .

18
alecxe

vous parcourez le dictionnaire et non les index, vous devez donc soit utiliser.

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

ou

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

La confusion réside dans la façon dont les dictionnaires et les listes sont utilisés dans l'itération. Un dictionnaire va parcourir ses clés (que vous utilisez comme indices pour obtenir les valeurs correspondantes)

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)

mais le comportement par défaut d'itération sur une liste vous donnera les éléments au lieu des 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)

Si vous souhaitez généraliser votre programme pour gérer les deux types de la même manière, vous pouvez utiliser l'une de ces fonctions:

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

de cette façon, si vous, par exemple, modifiez plus tard le json pour stocker les résultats dans un dict en utilisant l'id comme clés, le programme continuera à le parcourir de la même manière:

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

#or
for i in indices(data["Results"]):
    print(data["Results"][i]["name"])
3
for json_data in data['Results']:
    for attribute, value in json_data.iteritems():
        print attribute, value # example usage
1
mukesh mali