Iterazione attraverso un oggetto JSON


109

Sto cercando di iterare attraverso un oggetto JSON per importare dati, ad esempio titolo e collegamento. Non riesco ad arrivare al contenuto che è passato il :.

JSON:

[
    {
        "title": "Baby (Feat. Ludacris) - Justin Bieber",
        "description": "Baby (Feat. Ludacris) by Justin Bieber on Grooveshark",
        "link": "http://listen.grooveshark.com/s/Baby+Feat+Ludacris+/2Bqvdq",
        "pubDate": "Wed, 28 Apr 2010 02:37:53 -0400",
        "pubTime": 1272436673,
        "TinyLink": "http://tinysong.com/d3wI",
        "SongID": "24447862",
        "SongName": "Baby (Feat. Ludacris)",
        "ArtistID": "1118876",
        "ArtistName": "Justin Bieber",
        "AlbumID": "4104002",
        "AlbumName": "My World (Part II);\nhttp://tinysong.com/gQsw",
        "LongLink": "11578982",
        "GroovesharkLink": "11578982",
        "Link": "http://tinysong.com/d3wI"
    },
    {
        "title": "Feel Good Inc - Gorillaz",
        "description": "Feel Good Inc by Gorillaz on Grooveshark",
        "link": "http://listen.grooveshark.com/s/Feel+Good+Inc/1UksmI",
        "pubDate": "Wed, 28 Apr 2010 02:25:30 -0400",
        "pubTime": 1272435930
    }
]

Ho provato a usare un dizionario:

def getLastSong(user,limit):
    base_url = 'http://gsuser.com/lastSong/'
    user_url = base_url + str(user) + '/' + str(limit) + "/"
    raw = urllib.urlopen(user_url)
    json_raw= raw.readlines()
    json_object = json.loads(json_raw[0])

    #filtering and making it look good.
    gsongs = []
    print json_object
    for song in json_object[0]:   
        print song

Questo codice stampa solo le informazioni precedenti :. ( ignora la traccia di Justin Bieber :))

Risposte:


79

Il caricamento dei dati JSON è un po 'fragile. Invece di:

json_raw= raw.readlines()
json_object = json.loads(json_raw[0])

dovresti davvero fare solo:

json_object = json.load(raw)

Non dovresti pensare a ciò che ottieni come un "oggetto JSON". Quello che hai è un elenco. L'elenco contiene due dict. I dict contengono varie coppie chiave / valore, tutte stringhe. Quando lo fai json_object[0], stai chiedendo il primo dict nell'elenco. Quando si ripete su questo, con for song in json_object[0]:, si itera sulle chiavi del dettato. Perché è quello che ottieni quando ripeti il ​​dict. Se si desidera accedere al valore associato con la chiave in questa dict, si può usare, per esempio, json_object[0][song].

Niente di tutto questo è specifico per JSON. Sono solo tipi di Python di base, con le loro operazioni di base come coperte in qualsiasi tutorial.


non lo capisco. Ho provato a ripetere quello che dice il tuo detto fuori dai limiti. Sono abbastanza sicuro che sia una domanda su json
myusuf3

7
No. Ti sto dicendo che l'iterazione del comando ti dà le chiavi. Se vuoi iterare su qualcos'altro, dovrai iterare su qualcos'altro. Non hai detto quello che volevi ripetere. Un tutorial su Python sarebbe un buon posto per scoprire su cosa puoi iterare e cosa farebbe.
Thomas Wouters

5
Sfortunatamente è un po 'difficile spiegare tutti i modi in cui puoi estrarre dati da elenchi e dizionari e stringhe nei 600 caratteri che puoi inserire in un commento. Ho già detto che dovresti indicizzare il dict per ottenere il valore associato a una chiave. Non sono sicuro di cosa vuoi ripetere. Imparare a conoscere i tipi Python incorporati è il passo successivo.
Thomas Wouters

Non c'è molta iterazione quando vuoi ottenere singoli elementi. Forse quello su cui vuoi iterare è json_object, no json_object[0], e quindi ottenere singoli elementi da ogni dict.
Thomas Wouters

101

Credo che probabilmente intendevi:

from __future__ import print_function

for song in json_object:
    # now song is a dictionary
    for attribute, value in song.items():
        print(attribute, value) # example usage

NB: potresti usare al song.iteritemsposto di song.itemsif in Python 2.


per attributo, valore in song.iteritems (): cosa significa la virgola in questa riga?
zakdances

È lo stesso di for (attribute, value) in song.iteritems():, o (var1, var2) = (1, 2)o var1, var2 = 1, 2. dict.iteritems()produce (key, value)coppie (tuple). Cerca "spacchettamento tupla python".
tzot

1
Per Python 3, cambia song.iteritemsin song.items.
Big Pumpkin

44

Questa domanda è stata qui fuori da molto tempo, ma volevo contribuire al modo in cui di solito itero attraverso un oggetto JSON. Nell'esempio seguente, ho mostrato una stringa hardcoded che contiene il JSON, ma la stringa JSON potrebbe provenire altrettanto facilmente da un servizio Web o da un file.

import json

def main():

    # create a simple JSON array
    jsonString = '{"key1":"value1","key2":"value2","key3":"value3"}'

    # change the JSON string into a JSON object
    jsonObject = json.loads(jsonString)

    # print the keys and values
    for key in jsonObject:
        value = jsonObject[key]
        print("The key and value are ({}) = ({})".format(key, value))

    pass

if __name__ == '__main__':
    main()

2
Non vi è alcun indice di stringa nel codice precedente; jsonObjectè un dict. Nel codice sopra, preferirei for key, value in jsonObject.items():.
tzot

22

Dopo aver deserializzato il JSON, hai un oggetto Python. Usa i normali metodi degli oggetti.

In questo caso hai una lista fatta di dizionari:

json_object[0].items()

json_object[0]["title"]

eccetera.


8

Risolverei questo problema più come questo

import json
import urllib2

def last_song(user, limit):
    # Assembling strings with "foo" + str(bar) + "baz" + ... generally isn't 
    # as nice as using real string formatting. It can seem simpler at first, 
    # but leaves you less happy in the long run.
    url = 'http://gsuser.com/lastSong/%s/%d/' % (user, limit)

    # urllib.urlopen is deprecated in favour of urllib2.urlopen
    site = urllib2.urlopen(url)

    # The json module has a function load for loading from file-like objects, 
    # like the one you get from `urllib2.urlopen`. You don't need to turn 
    # your data into a string and use loads and you definitely don't need to 
    # use readlines or readline (there is seldom if ever reason to use a 
    # file-like object's readline(s) methods.)
    songs = json.load(site)

    # I don't know why "lastSong" stuff returns something like this, but 
    # your json thing was a JSON array of two JSON objects. This will 
    # deserialise as a list of two dicts, with each item representing 
    # each of those two songs.
    #
    # Since each of the songs is represented by a dict, it will iterate 
    # over its keys (like any other Python dict). 
    baby, feel_good = songs

    # Rather than printing in a function, it's usually better to 
    # return the string then let the caller do whatever with it. 
    # You said you wanted to make the output pretty but you didn't 
    # mention *how*, so here's an example of a prettyish representation
    # from the song information given.
    return "%(SongName)s by %(ArtistName)s - listen at %(link)s" % baby

3

per iterare attraverso JSON puoi usare questo:

json_object = json.loads(json_file)
for element in json_object: 
    for value in json_object['Name_OF_YOUR_KEY/ELEMENT']:
        print(json_object['Name_OF_YOUR_KEY/ELEMENT']['INDEX_OF_VALUE']['VALUE'])

2

Per Python 3, devi decodificare i dati che ricevi dal server web. Ad esempio, decodifico i dati come utf8 e poi li gestisco:

 # example of json data object group with two values of key id
jsonstufftest = '{'group':{'id':'2','id':'3'}}
 # always set your headers
headers = {'User-Agent': 'Moz & Woz'}
 # the url you are trying to load and get json from
url = 'http://www.cooljson.com/cooljson.json'
 # in python 3 you can build the request using request.Request
req = urllib.request.Request(url,None,headers)
 # try to connect or fail gracefully
try:
    response = urllib.request.urlopen(req) # new python 3 code -jc
except:
    exit('could not load page, check connection')
 # read the response and DECODE
html=response.read().decode('utf8') # new python3 code
 # now convert the decoded string into real JSON
loadedjson = json.loads(html)
 # print to make sure it worked
print (loadedjson) # works like a charm
 # iterate through each key value
for testdata in loadedjson['group']:
    print (accesscount['id']) # should print 2 then 3 if using test json

Se non decodifichi, otterrai byte vs errori di stringa in Python 3.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.