6

I am currently getting JSON data from the discogs API (mp3 tag data) and wish to sort the results by the key's value. In this case I am trying to get data for a Guns n Roses song and the output has 1988 as the first one while the data actually has a record from 1987. How can I sort this data so that I can get to the sorted data by year (olderst to newest). The code below sorts by either key or value but thats not what I intended to get. Please help.

import json
import urllib2
request = urllib2.Request('http://api.discogs.com/database/search?sort=year&sort_order=asc&artist=%22Guns+N%27+Roses%22&track=%22Sweet+Child+O%27+Mine%22&format_exact=Album&type=master')
request.add_header('User-Agent','Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)')
request.add_header('Content-Type','application/json')
response = urllib2.urlopen(request)
json_raw= response.readlines()
json_object = json.loads(json_raw[0])



for row in json_object['results']:
    try:
        from operator import itemgetter
        for k, v in sorted(row.items(), key=itemgetter(0)):
            print k, v
    except KeyError: 
        pass
2
  • 3
    I'd help if you included a sample of the JSON data.. Commented Nov 18, 2012 at 8:25
  • By the looks of it, you are using this API. Commented Nov 18, 2012 at 8:33

2 Answers 2

13

You could use list-comprehension and sorted() function for this:

# filter  json_object['results']  first, as some of the items are missing the key 'year'

In [33]: results = [x for x in json_object['results'] if 'year' in x]

In [34]: sorted(results, key=lambda x: x['year'])

or :

In [79]: from operator import itemgetter

In [80]: sorted(results, key=itemgetter('year'))
Sign up to request clarification or add additional context in comments.

1 Comment

Than you, this works like a charm, as you can tell, I am a newbie and have a long way to go..
1

To sort a list of dictionaries, use a methodcaller with the key on which to sort; you want to sort the results list, not the contained dictionaries. Moreover, some of the entries do not have a year, and that could lead to errors:

from operator import methodcaller

for row in sorted(json_object['results'], key=methodcaller('get', 'year', None)):
    # process the row dictionary

The methodcaller definition will basically do a entry.get('year', None) for each entry in json_object['results'], giving the sorted method the value to sort on.

You should not use readlines() to read your JSON response, it'll mis-interpret newlines. Let the json library do the reading instead (note the .load(), no s at the end):

response = urllib2.urlopen(request)
json_object = json.load(response)

5 Comments

I am new to this forum and I am unable to post the JSON as it says I have few characters left to post...
Take a look at How do I format my code blocks? for more help.
I am not sure what I am doing wrong, but when I run this now, I get an error:
C:\Python27>python test2.py Traceback (most recent call last): File "test2.py", line 11, in <module> for row in sorted(json_object['results'], key=itemgetter('year')): KeyError: 'year'
@PremMinister: I tested the code some more, and made an update. I switched techniques a little, actually.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.