Sort JSON in python by specific value

Hello, I am trying to sort the following JSON using the "data_two" field in python:

{ "1.2.3.4": { "data_one": 1, "data_two": 8, "list_one": [], "list_two": [ "item_one" ], "data_three": "string1" }, "5.6.7.8": { "data_one": 1, "data_two": 9, "list_two": [ "item_one" ], "data_three": "string1", "data_four": "string2", "data_five": "string3" } } 

I tried using something like

 entries = sorted(json_data['1.2.3.4'], key=lambda k: k['data_two']) 

However, I am not very lucky / continue to be embarrassed. My ultimate goal is to sort all json records by value "data_two", with the key for each record in JSON being a random IP-like string. I am new to the JSON world, so forgive me if this is a simple question, any help would be greatly appreciated.

thanks

+5
source share
2 answers

If you have control over how data is aggregated, it is better to have a list of dicts , and IP will be the value inside the data dict {..., 'ip': '127.0.0.1'} , and not the key in the parent type of the container

Convert to a container that preserves the order of elements

You can sort a structure that maintains the order of elements, for example list for example. there is a dict implementation that supports order, for example, OrderedDict , for example.

You can always convert them (maybe this is not your first choice if slow / big data)

Convert to list [(key, value), ...] or list [value, ...]

A possible way is to get all the values ​​in a dict and then return a list of these values, sorted of your choice.

You can also sort (key, value) returned by ips_data.items() , but about to create a new list. key is IP and value is IP data.

 sorted_list_of_keyvalues = sorted(ips_data.items(), key=item[1]['data_two']) 

The list above is in the form [(key1, value1), (key2, value2), ...]

You can also pull out values ​​and delete keys

 sorted_list_of_values = [item[1] for item in sorted_list_of_keyvalues] 

This list is in the form [value1, value2, ...]

Please note that you might think that you can only sort the value, not (the key value), but your data has an IP address in them, and you might want to keep this.

Convert to OrderedDict

If you absolutely want to keep the structure as a dict, you can use OrderedDict

 from collections import OrderedDict ordered_items = sorted(ips_data.items(), key=lambda item: item[1]['data_two']) ordered_ips_data_dict = OrderedDict(ordered_items) 

An ordered dict behaves exactly the same as a dict, but iterations of keys and elements will maintain the order of the elements.

Or save the sorted list of keys and process in that order

Or, alternatively, you can sort the keys of this dict in a list, then you can process the dict in that order. The advantage is that you do not need to copy / convert data

 >>> ips_data = { ... "1.2.3.4": { ... "data_one": 1, ... "data_two": 8, ... "list_one": [], ... "list_two": [ ... "item_one" ... ], ... "data_three": "string1" ... }, ... "5.6.7.8": { ... "data_one": 1, ... "data_two": 9, ... "list_two": [ ... "item_one" ... ], ... "data_three": "string1", ... "data_four": "string2", ... "data_five": "string3" ... } ... } >>> ips_data.keys() ['1.2.3.4', '5.6.7.8'] >>> ips = ips_data.keys() 

Now you can sort the keys by the data_two field

 >>> sorted_ips = sorted(ips, key=lambda ip: ips_data[ip]['data_two'], reverse=True) >>> sorted_ips ['5.6.7.8', '1.2.3.4'] 

After sorting the keys, you can do what you want in your sorted key order, for example. processing it in this order may be more efficient than copying a dict into a new structure such as a list

 # Trivial example of processing that just puts the values into a list >>> [ips_data[ip] for ip in sorted_ips] [{'data_three': 'string1', 'data_two': 9, 'data_five': 'string3', 'data_four': 'string2', 'list_two': ['item_one'], 'data_one': 1}, {'list_two': ['item_one'], 'data_two': 8, 'data_one': 1, 'data_three': 'string1', 'list_one': []}] >>> 
+1
source

It seems that what you tried was very close. Below you will get a sorted list of tuples with a key in the 0th position and a value (which is a dictionary) in the 1st position. You will need to use this to do what you would like later.

 entries = sorted(json_data.items(), key=lambda items: items[1]['data_two']) 

So for example

 { "k1": {"data_one": 1, "data_two": 50 ...}, "k2": {"data_one": 50, "data_two": 2}} 

will result in:

 [("k2", {..."data_two": 2...}), ("k1", {..."data_two": 50...})] 

Hope this helps!

+1
source

Source: https://habr.com/ru/post/1237626/


All Articles