Python按不同类型的2个键值排序json列表

时间:2018-01-23 15:12:50

标签: python json

我一直在听这个答案: Python sort a JSON list by two key values

我想根据我的情况进行调整:

[
    {'score': 0.1, 'id': 1, 'flag': true}, 
    {'score': 0.234, 'id': 2, 'flag': false}, 
    {'score': 0.4, 'id': 3, 'flag': false}
]

我需要按标志(布尔值)和得分(浮点)排序,就像你在SQL中做的那样。 在这种情况下,结果将是:

[
    {'score': 0.1, 'id': 1, 'flag': true}, // first because the flag is true
    {'score': 0.4, 'id': 3, 'flag': false} //second because the score is higher 
    {'score': 0.234, 'id': 2, 'flag': false}, 

]

我正在尝试使用

sorted_result = sorted(json, key=lambda k: (bool(k['flag']), -float(k['score'])))

但它没有按预期排序

3 个答案:

答案 0 :(得分:2)

也是否定flag

>>> data = [{'score': 0.1, 'id': 1, 'flag': True}, 
            {'score': 0.234, 'id': 2, 'flag': False}, 
            {'score': 0.4, 'id': 3, 'flag': False}]

>>> sorted(data, key = lambda k: (-k['flag'], -k['score']))
[{'score': 0.1, 'id': 1, 'flag': True}, {'score': 0.4, 'id': 3, 'flag': False}, {'score': 0.234, 'id': 2, 'flag': False}]

您也不需要在此处对bool()float()进行类型转换,因为已经推断出类型。

答案 1 :(得分:1)

您可以使用lambda函数返回元组作为排序键。您也可以使用reverse=True而不是否定值以降序排序:False之前为True,大值为小值。

j = [
    {'score': 0.1, 'id': 1, 'flag': True},
    {'score': 0.234, 'id': 2, 'flag': False},
    {'score': 0.4, 'id': 3, 'flag': False}
]

sorted(j, key=lambda x: (x.get('flag'), x.get('score')), reverse=True)
# returns:
[{'flag': True, 'id': 1, 'score': 0.1},
 {'flag': False, 'id': 3, 'score': 0.4},
 {'flag': False, 'id': 2, 'score': 0.234}]

如果从字符串加载json,请使用:

import json
j = json.loads('''[
    {"score": 0.1, "id": 1, "flag": true}, 
    {"score": 0.234, "id": 2, "flag": false}, 
    {"score": 0.4, "id": 3, "flag": false}
]''')

答案 2 :(得分:0)

如果您尝试对一个升序为int / float的值进行排序,并且如果存在平局,则对另一个升序为字符串的值进行排序,就可以了:D:

arr = [{'score': 10, 'name': 'Helen'},{'score': 10, 'name': 'Zed'},{'score': 10, 'name': 'Bob'}, {'score': 15, 'name':'Susan'}, {'score': 1, 'name': 'Skippy'}]
arr

[{'score': 10, 'name': 'Helen'},
 {'score': 10, 'name': 'Zed'},
 {'score': 10, 'name': 'Bob'},
 {'score': 15, 'name': 'Susan'},
 {'score': 1, 'name': 'Skippy'}]

sorted(arr, key = lambda k: (k['score'], k['name']))

[{'score': 1, 'name': 'Skippy'},
 {'score': 10, 'name': 'Bob'},
 {'score': 10, 'name': 'Helen'},
 {'score': 10, 'name': 'Zed'},
 {'score': 15, 'name': 'Susan'}]