Python按两个值对列表进行排序

时间:2013-09-02 11:11:33

标签: python sorting

我正在尝试首先按名称排序此列表。然后,在第一组结果(其中flag =“ZAR”)之后,我想按时间排序剩余的元素而不是反过来:

import operator
list = [
    {"flag":"ZAR", "time":"17:45"},
    {"flag":"AUS", "time":"17:30"},
    {"flag":"AUS", "time":"17:15"},
    {"flag":"USA", "time":"17:00"},
    {"flag":"GBP", "time":"16:55"},
    {"flag":"ZAR", "time":"16:45"},
    {"flag":"USA", "time":"16:35"},
    {"flag":"GBP", "time":"16:25"},
    {"flag":"ZAR", "time":"16:15"},
]

list.sort(key=operator.itemgetter("time"))
list.sort(key=operator.itemgetter("flag"),reverse=True)


print list

[{'flag': 'ZAR', 'time': '16:15'}, {'flag': 'ZAR', 'time': '16:45'}, {'flag': 'ZAR', 'time': '17:45'}, {'flag': 'USA', 'time': '16:35'}, {'flag': 'USA', 'time': '17:00'}, {'flag': 'GBP', 'time': '16:25'}, {'flag': 'GBP', 'time': '16:55'}, {'flag': 'AUS', 'time': '17:15'}, {'flag': 'AUS', 'time': '17:30'}]

正如您所见,标记排序已正确完成,但其他元素仅按排序国家/地区的时间排序。

我想要的是始终拥有ZAR,之后标志名称是什么,只有时间。所以它应该给出这个结果:

[{'flag': 'ZAR', 'time': '16:15'}, {'flag': 'ZAR', 'time': '16:45'}, {'flag': 'ZAR', 'time': '17:45'}, {'flag': 'GBP', 'time': '16:25'}, {'flag': 'USA', 'time': '16:35'}, {'flag': 'GBP', 'time': '16:55'}, {'flag': 'USA', 'time': '17:00'}, {'flag': 'AUS', 'time': '17:15'}, {'flag': 'AUS', 'time': '17:30'}]

如何做到这一点?

1 个答案:

答案 0 :(得分:5)

将您的代码修改为:

import operator
data = [
    {"flag":"ZAR", "time":"17:45"},
    {"flag":"AUS", "time":"17:15"},
    {"flag":"USA", "time":"17:00"},
    {"flag":"GBP", "time":"16:55"},
    {"flag":"ZAR", "time":"16:45"},
    {"flag":"USA", "time":"16:35"},
    {"flag":"GBP", "time":"16:25"},
    {"flag":"ZAR", "time":"16:15"},
]

data.sort(key=operator.itemgetter("time"))
data.sort(key=lambda L: L['flag'] == 'ZAR', reverse=True)

# [{'flag': 'ZAR', 'time': '16:15'}, {'flag': 'ZAR', 'time': '16:45'}, {'flag': 'ZAR', 'time': '17:45'}, {'flag': 'GBP', 'time': '16:25'}, {'flag': 'USA', 'time': '16:35'}, {'flag': 'GBP', 'time': '16:55'}, {'flag': 'USA', 'time': '17:00'}, {'flag': 'AUS', 'time': '17:15'}, {'flag': 'AUS', 'time': '17:30'}]