参考文章
前言
最近写业务学到了在Golang中给slice中的map按照key排序的方法,想到Python中也有相关的需求与写法,总结一下方便以后使用。
Golang中的实现
在Go中有一个内置的sort模块可以实现:
package test1
import (
"fmt"
"sort"
"testing"
)
/*
数据的格式如下:
s=[
{"no":21,"score":90},
{"no":21,"score":80},
{"no":25,"score":100},
{"no":20,"score":66},
]
*/
func TestSortSliceMap(t *testing.T) {
m1 := map[string]int{"no": 21, "score": 90}
m2 := map[string]int{"no": 21, "score": 80}
m3 := map[string]int{"no": 25, "score": 100}
m4 := map[string]int{"no": 20, "score": 66}
s1 := []map[string]int{m1, m2, m3, m4}
// 排序后
fmt.Println("排序前s1: ", s1)
// 先根据no排序,no一样的话再根据score排序 ———— 从小到大排序
sort.Slice(s1, func(i, j int) bool {
if s1[i]["no"] == s1[j]["no"] {
return s1[i]["score"] < s1[j]["score"]
}
return s1[i]["no"] < s1[j]["no"]
})
// 排序后
fmt.Println("排序后s1: ", s1)
/*
结果:
排序前s1: [map[no:21 score:90] map[no:21 score:80] map[no:25 score:100] map[no:20 score:66]]
排序后s1: [map[no:20 score:66] map[no:21 score:80] map[no:21 score:90] map[no:25 score:100]]
*/
}
Python中的实现
简单的按照value排序
dic = {'a': 21, 'b': 5, 'c': 3, 'd': 54, 'e': 74, 'f': 0}
# 按照value的大小倒序排序
new_lst = sorted(dic.items(), key=lambda d: d[1], reverse=True)
print("new_lst: ", new_lst)
# new_lst: [('e', 74), ('d', 54), ('a', 21), ('b', 5), ('c', 3), ('f', 0)]
# 重新构建字典
new_dic = {tu[0]: tu[1] for tu in new_lst}
print("new_dic: ", new_dic)
# new_dic: {'e': 74, 'd': 54, 'a': 21, 'b': 5, 'c': 3, 'f': 0}
列表里面嵌套字典按照字典的多个key排序
import pprint
lst = [
{"level": 19, "star":21, "time": 9},
{"level": 29, "star":43, "time": 51},
{"level": 22, "star":55, "time": 43},
{"level": 22, "star":66, "time": 3},
{"level": 17, "star":20, "time": 12},
{"level": 17, "star":20, "time": 13},
]
"""
需求:
level越大越靠前;
level相同, star越大越靠前;
level和star相同, time越小越靠前;
"""
print("lst0: ")
pprint.pprint(lst)
# 先按照time排序 默认是从小到大
lst.sort(key=lambda k:k["time"])
print("lst1: ")
pprint.pprint(lst)
# 再根据level跟star排序,从大到小
lst.sort(key=lambda k: (k["level"], k["star"]), reverse=True)
print("lst2: ")
pprint.pprint(lst)
"""
结果:
lst0:
[{'level': 19, 'star': 21, 'time': 9},
{'level': 29, 'star': 43, 'time': 51},
{'level': 22, 'star': 55, 'time': 43},
{'level': 22, 'star': 66, 'time': 3},
{'level': 17, 'star': 20, 'time': 12},
{'level': 17, 'star': 20, 'time': 13}]
lst1:
[{'level': 22, 'star': 66, 'time': 3},
{'level': 19, 'star': 21, 'time': 9},
{'level': 17, 'star': 20, 'time': 12},
{'level': 17, 'star': 20, 'time': 13},
{'level': 22, 'star': 55, 'time': 43},
{'level': 29, 'star': 43, 'time': 51}]
lst2:
[{'level': 29, 'star': 43, 'time': 51},
{'level': 22, 'star': 66, 'time': 3},
{'level': 22, 'star': 55, 'time': 43},
{'level': 19, 'star': 21, 'time': 9},
{'level': 17, 'star': 20, 'time': 12},
{'level': 17, 'star': 20, 'time': 13}]
"""
Golang中给切片中的结构体排序 ***
Go中的排序函数如下:
1. Slice() 不稳定排序
2. SliceStable() 稳定排序
3. SliceIsSorted() 判断是否已排序
package sort_tests
import (
"fmt"
"sort"
"testing"
)
type UserTask struct {
Id int
Name string
Type string
}
// slice里面是 结构体,根据结构体的某个字段去排序
func TestSortStructSlice(t *testing.T) {
userTask1 := UserTask{Id: 1, Name: "task1", Type: "type1"}
userTask2 := UserTask{Id: 2, Name: "task2", Type: "type2"}
userTask3 := UserTask{Id: 3, Name: "task3", Type: "type3"}
userTask4 := UserTask{Id: 4, Name: "task4", Type: "type4"}
userTask5 := UserTask{Id: 5, Name: "task5", Type: "type5"}
mySlice := []UserTask{userTask4, userTask3, userTask1, userTask5, userTask2}
fmt.Println("=========排序前:==========", mySlice)
// [{4 task4 type4} {3 task3 type3} {1 task1 type1} {5 task5 type5} {2 task2 type2}]
// 1、从小到大排序 不稳定排序
sort.Slice(mySlice, func(i, j int) bool {
if mySlice[i].Id < mySlice[j].Id {
return true
}
return false
})
fmt.Println("=========不稳定排序(从小到大)后:=========", mySlice)
// [{1 task1 type1} {2 task2 type2} {3 task3 type3} {4 task4 type4} {5 task5 type5}]
// 2、判断是否是 从小到大排序
bLess := sort.SliceIsSorted(mySlice, func(i, j int) bool {
if mySlice[i].Id < mySlice[i].Id {
return true
}
return false
})
fmt.Println("======是否是从小到大排序: ", bLess) // true
// 3、从大到小排序 稳定排序
sort.SliceStable(mySlice, func(i, j int) bool {
if mySlice[i].Id > mySlice[j].Id {
return true
}
return false
})
fmt.Println("=========稳定排序(从大到小)后:=========", mySlice)
// [{5 task5 type5} {4 task4 type4} {3 task3 type3} {2 task2 type2} {1 task1 type1}]
// 4、判断是否是 从大到小排序
bMore := sort.SliceIsSorted(mySlice, func(i, j int) bool {
if mySlice[i].Id > mySlice[i].Id {
return true
}
return false
})
fmt.Println("======是否是从小到大排序: ", bMore) // true
}
~~~