简体   繁体   English

按特定值对python中的JSON进行排序

[英]Sorting JSON in python by a specific value

Hello I am trying to sort the following JSON by the "data_two" field in python: 您好我试图通过python中的“data_two”字段对以下JSON进行排序:

{
"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 have tried using something like 我尝试过使用类似的东西

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

However I am not having much luck / keep getting confused. 然而,我没有太多运气/不断混淆。 My ultimate goal is to sort all of the json entries by the "data_two" value, with the key for each entry in the JSON being a random IP like string. 我的最终目标是通过“data_two”值对所有json条目进行排序,其中JSON中每个条目的键是一个随机的IP字符串。 I am new to the world of JSON so forgive me if this is a simple question, any help would be greatly appreciated. 我是JSON世界的新手,请原谅我,如果这是一个简单的问题,任何帮助将不胜感激。

Thank you 谢谢

If you have control over how the data is aggregated, it's better to have a list of dicts , and the IP would be a value inside the data dict {..., 'ip': '127.0.0.1'} , not a key in the container parent dict 如果你有过如何将数据汇总控制, 最好是有类型的字典列表 ,而IP将是数据字典中的 {..., 'ip': '127.0.0.1'}而不是关键在容器父dict中

Convert to a container that preserves element order 转换为保留元素顺序的容器

You can only sort a structure that maintains elements order, like a list eg there are dict implementation that maintain order like OrderedDict eg 您只能对维护元素顺序的结构进行排序,例如list例如,存在像OrderedDict一样维护顺序的dict实现

You can always convert to those (might not be your first choice if slow/big data) 您可以随时转换为那些(如果慢/大数据可能不是您的首选)

Converting to a list [(key, value), ...] or list [value, ...] 转换为列表[(键,值),...]或列表[value,...]

A possible way is to retrieve all values in the dict and then return a list of those values, sorted by your field of choice 一种可能的方法是检索dict中的所有值,然后返回这些值的列表,按您选择的字段排序

You can also sort the (key, value) returned by ips_data.items() , but that's going to create a new list. 您还可以对by ips_data.items()返回的(key, value) by ips_data.items() ,但这将创建一个新列表。 key being the IP, and value being the IP data key是IP, value是IP数据

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

The list above in the form of [(key1, value1), (key2, value2), ...] 上面的列表以[(key1, value1), (key2, value2), ...]

You can also pluck the values and remove the keys 您还可以获取值并删除键

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

This list is in the form of [value1, value2, ...] 此列表的形式为[value1, value2, ...]

Note that you might think that you can sort by just value instead of (key. value), but your data has the IP in they key and you might want to keep that. 请注意,您可能认为您只能按值而不是(键。值)进行排序,但您的数据中包含IP密钥,您可能希望保留它。

Converting to an OrderedDict 转换为OrderedDict

If you absolutely want to keep the structure as a dict, you can use an OrderedDict 如果您绝对希望将结构保留为dict,则可以使用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)

The ordered dict behaves just like a dict, but keys and items iteration will maintain the order of elements. 有序的dict行为就像一个dict,但是key和items迭代将保持元素的顺序。

Or, Keep a sorted list of keys, and process in that order 或者,保留已排序的键列表,并按此顺序处理

Or alternatively, you can sort the keys of that dict into a list, then you can process the dict in that order. 或者,您可以将该字典的键排序到列表中,然后您可以按顺序处理该字典。 Advantage is you don't have to copy/convert the 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 field data_two 现在,您可以按字段data_two对键进行排序

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

Having sorted keys, you can do what you want to your dict, in that sorted keys order, eg processing it in this order might be more efficient than copying the dict into a new structure like a list 排序后的键,您可以按照排序的键顺序执行您想要的dict,例如按此顺序处理它可能比将dict复制到像列表这样的新结构更有效

# 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': []}]
>>> 

It looks like what you tried was really close. 看起来你尝试的非常接近。 Below will get you a sorted list of tuples, with the key in the 0th position and the value (which is a dictionary) in the 1st position. 下面将为您提供一个排序的元组列表,其中键位于第0位,值(位于字典中)位于第1位。 You should be able to use this to do what you'd like afterward. 你应该能够使用它来做你想做的事情。

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

would result in: 会导致:

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

Hope that helps! 希望有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM