python 对list表嵌套dict,list,tuple进行多列排序,实现模拟数据库进行简单的多列,多字段排序,考虑了none值,字段空缺,下表超出等异常状况.python
def multi_sorted(data_list, sort_config):
'''
多字段排序
:param data_list:
:param args: 为空的话,不排序
args=[
("field1",1),升序
("field2",-1),降序
("field3",1),
]
:return:
'''
from functools import cmp_to_key
def _comp_fn(a, b, sort_config):
# if not args: return 0
for i in sort_config:
k = i[0]
n = i[1]
if isinstance(a, dict):
va = a.get(k, None)
vb = b.get(k, None)
elif isinstance(a, tuple) or isinstance(a, list):
lena = len(a)
lenb = len(b)
va = a[k] if k < lena else None
vb = b[k] if k < lenb else None
else:
va = a
vb = b
if va != vb:
if va is None:
return n * -1
if vb is None:
return n
return (va - vb) * n
return 0
# return sorted(data_list, cmp=lambda a, b: _comp_fn(a, b, sort_config)) 只适用python2,python3移除了cmp参数
return sorted(data_list, key=cmp_to_key(lambda a, b: _comp_fn(a, b, sort_config)))
if __name__ == '__main__':
ll = [
{
"a": None,
"b": 1,
"c": 11,
},
{
"a": None,
"b": 12,
"c": 13,
"d": 4,
},
{
"a": None,
"b": 12,
"c": 13,
},
]
args = [
("a", 1), # 升序
("b", -1), # 降序
("d", 1), # 升序
("e", -1), # 降序
]
lll = [
(1, 2),
(3, 4),
(3, 4, 11),
]
args2 = [
(2, -1), # 下标2 降序
]
# 嵌套字典
print(multi_sorted(ll, args));
# 嵌套元组
print(multi_sorted(lll, args2));
# 输出
# [{'a': None, 'c': 13, 'b': 12}, {'a': None, 'c': 13, 'b': 12, 'd': 4}, {'a': 1, 'c': 11, 'b': 1, 'e': 'xx'}]
# [(3, 4, 11), (1, 2), (3, 4)]
另一种方法数据库
print(sorted(ll, key=lambda tm: (tm["a"], -tm["b"])))
# [{'a': None, 'c': 13, 'b': 12, 'd': 4}, {'a': None, 'c': 13, 'b': 12}, {'a': 1, 'c': 11, 'b': 1, 'e': 'xx'}]