0

I need to print line for line a static json file. I would like to sort this by a key value prior to printing. I have looked at several other examples on stackoverflow, but was unable to find a solution to this particular problem.

My code so far looks like this:

import json
from pprint import pprint
with open('items.json') as data_file:
    data = json.load(data_file)
    for line in data:
        pprint(data)

My json looks like this:

[
{"version": ["2.8.2"], "license": ["GPL"]},
{"version": ["1.8.8"], "license": ["MIT/X11 License"]},
{"version": ["2.8.5"], "license": ["GPL"]},
{"version": ["1.8.9"], "license": ["MIT/X11 License"]}
]

How can I sort it by a key value such as "version" while preserving order? In this way I can determine at which version the license was changed.

Desired output would look like this:

[
{"version": ["1.8.8"], "license": ["MIT/X11 License"]},
{"version": ["1.8.9"], "license": ["MIT/X11 License"]},
{"version": ["2.8.2"], "license": ["GPL"]},
{"version": ["2.8.5"], "license": ["GPL"]}
]

Thank you.

tonemgub
  • 35
  • 1
  • 1
  • 7
  • `for line in data: pprint(data)` is never going to give your desired output, so I have to clarify, are you looking to get valid JSON as the output, or do you just want something sorted and pretty? – Alex Hall Nov 29 '16 at 14:12
  • Just sorted and pretty in this case. – tonemgub Nov 29 '16 at 14:17

2 Answers2

1

You just need to sort your list of dicts with an appropriate key function. You could use a lambda, but itemgetter is more efficient.

import json
from pprint import pprint
from operator import itemgetter

data_str = '''\
[
    {"version": ["2.8.2"], "license": ["GPL"]},
    {"version": ["1.8.8"], "license": ["MIT/X11 License"]},
    {"version": ["2.8.5"], "license": ["GPL"]},
    {"version": ["1.8.9"], "license": ["MIT/X11 License"]}
]
'''

data = json.loads(data_str)
data.sort(key=itemgetter("version"))
pprint(data)

output

[   {'license': ['MIT/X11 License'], 'version': ['1.8.8']},
    {'license': ['MIT/X11 License'], 'version': ['1.8.9']},
    {'license': ['GPL'], 'version': ['2.8.2']},
    {'license': ['GPL'], 'version': ['2.8.5']}]
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
  • Thank you for offering your solution! I am not dealing with a large data set, but I assume by efficiency you mean itemgetter is faster compared to lambda? – tonemgub Nov 29 '16 at 14:31
  • @tonemgub Yes, `itemgetter` is faster than using an equivalent lambda, but it's good to know both ways, because sometimes you need a key function that does more than what `itemgetter` can do. – PM 2Ring Nov 29 '16 at 14:34
0

It looks like the data is already in dictionary form so something like:

sorted_data = sorted(data, key = lambda x: x['version'])

And then pretty-print that structure.

Edit: you can print the whole structure with one line, by the way:

pprint.pprint(sorted_data, indent=4)

should look pretty nice.

For more information on the lambda expression, have a look at this SO thread: What is key=lambda

Community
  • 1
  • 1
Andrew
  • 518
  • 2
  • 9
  • Yes, this does exactly what I wanted. I will read up more about the lamda function. Thank you for your help! – tonemgub Nov 29 '16 at 14:18
  • @tonemgub Glad to help! I added a link to a good summary of using lambda. Don't forget to accept whichever answer you like best (I see there is another one that is good too) – Andrew Nov 29 '16 at 14:21