【问题标题】:Sorting JSON in python by a specific value按特定值对python中的JSON进行排序
【发布时间】:2016-03-12 22:40:57
【问题描述】:

您好,我正在尝试通过 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"
}
}

我尝试过使用类似的东西

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

但是我运气不佳/一直感到困惑。我的最终目标是按“data_two”值对所有 json 条目进行排序,JSON 中每个条目的键都是随机 IP,如字符串。我是 JSON 世界的新手,所以如果这是一个简单的问题,请原谅我,任何帮助将不胜感激。

谢谢

【问题讨论】:

  • 您不能对字典进行排序。 Python 字典是无序的。为了排序,您必须首先将字典转换为列表(或使用OrderedDict)。

标签: python json python-2.7


【解决方案1】:

如果您可以控制数据的聚合方式,it's better to have a list of dicts,并且 IP 将是数据字典 {..., 'ip': '127.0.0.1'} 内的 ,而不是 在容器父字典中

转换为保留元素顺序的容器

您只能对保持元素顺序的结构进行排序,例如 listdict 的实现可以像OrderedDict 这样维护秩序,例如

您始终可以转换为那些(如果数据慢/大数据可能不是您的首选)

转换为列表 [(key, value), ...] 或列表 [value, ...]

一种可能的方法是检索 dict 中的所有值,然后返回这些值的列表,按您选择的字段排序

您也可以对返回的(key, value) 排序by ips_data.items(),但这会创建一个新列表。 key 是 IP,value 是 IP 数据

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

以上列表形式为[(key1, value1), (key2, value2), ...]

您还可以提取值并删除键

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

此列表的格式为[value1, value2, ...]

请注意,您可能认为您可以仅按值而不是 (key.value) 进行排序,但您的数据在其键中包含 IP,您可能希望保留它。

转换为 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)

有序 dict 的行为就像一个 dict,但键和项迭代将保持元素的顺序。

或者,保留一个排序的键列表,并按该顺序处理

或者,您可以将该字典的键排序到一个列表中,然后您可以按该顺序处理该字典。优点是您不必复制/转换数据

>>> 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()

现在您可以按字段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']

拥有排序的键,您可以按照排序的键顺序对您的 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': []}]
>>> 

【讨论】:

    【解决方案2】:

    看起来你尝试的非常接近。下面将为您提供一个排序的元组列表,其中键位于第 0 位,值(这是一个字典)位于第 1 位。之后您应该可以使用它来做您想做的事情。

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

    例如

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

    会导致:

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

    希望有帮助!

    【讨论】:

      猜你喜欢
      • 2016-09-21
      • 2023-03-30
      • 2010-10-27
      • 1970-01-01
      • 2014-09-16
      • 2021-03-28
      • 2016-07-02
      • 1970-01-01
      • 2021-10-12
      相关资源
      最近更新 更多