sorted()函数与lambda()匿名函数
示例代码如下:
根据列表中每个元素的 b键所对应的值进行降序排列。
1 ls = [{"a": 1, "b": 2, "c": 4}, {"a": 11, "b": 4, "c": 16}, {"a": 11, "b": 4, "c": 16}] 2 ls_sorted = sorted(ls, key=lambda d: d["b"], reverse=True) 3 print(ls_sorted) # [{'a': 11, 'b': 4, 'c': 16}, {'a': 11, 'b': 4, 'c': 16}, {'a': 1, 'b': 2, 'c': 4}]
一: lambda匿名函数:
lambda表达式(又称匿名函数),用于封装有限的逻辑的函数
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去
常用方式:
1:函数式编程
my_list = [3, 5, -1, 0, -2, -6] # 对其绝对值进行排序 my_list = sorted(my_list, key=lambda x: abs(x)) print(my_list) # [0, -1, -2, 3, 5, -6]
2:结合filter(), map(), reduce() 一起使用的
print(list(map(lambda x:x*x, range(1, 21)))) print(list(filter(lambda x:x%2 == 0, range(1, 21)))) # python 3.0以上的版本需要导入 from functools import reduce print(reduce(lambda x, y: x+y, range(1, 101))) print(reduce(lambda x, y:x+y, range(1, 101), 10000))
3:闭包
def test(n): return lambda x: x+n test1 = test(5) test2 = test1(30) print(test2) # 35
二 sorted()内置函数:
将可迭代的对象的数据重新排序,生成新的列表
sorted(iters, key=None, reverse=None)
iters: 可迭代对象
key: 指定按key的值进行排序
reverse: boolean值,True: 倒序; Flase: 正序
返回值为一个列表。
sorted(L): 返回一个新的列表,原列表不改变
L.sort(): 不返回值,改变原列表
ll = [5, -4, 1, -2, 0, 3] print(sorted(ll)) # [-4, -2, 0, 1, 3, 5] # 按绝对值排序 print(sorted(ll, key=abs)) # [0, 1, -2, 3, -4, 5] # 按绝对值倒叙 print(sorted(ll, key=abs, reverse=True)) # [5, -4, 3, -2, 1, 0]
sorted原理解析
def my_sorted(iters, key=None, reverse=None): if key: DICT = dict() for it in iters: # 用函数处理过后的值做键, 处理相同的键加入列表 DICT.setdefault(key(it), []).append(it) INDEX = list(DICT) INDEX.sort(reverse=reverse) # 排序 return [xx for x in INDEX for xx in DICT[x]] else: INDEX = list(iters) INDEX.sort(reverse=reverse) return INDEX names = ["Tom", "Spike", "Jerry", "Tyke"] L = sorted(names, key=len, reverse=True) print(L) # ['Spike', 'Jerry', 'Tyke', 'Tom'] L = my_sorted(names, key=len, reverse=True) print(L) # ['Spike', 'Jerry', 'Tyke', 'Tom']
lambda函数与sorted()结合使用:
1 # 对列表里的字典排序 2 L = [{'a': 1, 'b': 4}, {'a': 1111, 'b': 2}, {'a': 1111, 'b': 3}] 3 l_sorted = sorted(L, key=lambda d: d["b"], reverse=False) 4 print(l_sorted) 5 # 对字典进行key排序 6 d = {'a':25, 'c':27, 'b':20, 'd':22} 7 l_s = sorted(d.items(), key=lambda x: x[0]) 8 print(l_s) 9 # 对字典进行values排序 10 l_s1 = sorted(d.items(), key=lambda x: x[1]) 11 print(l_s1)
降序的另一种方式: ord()函数转为编码值,再 * -1
1 Data = [['y', 2], ['x', 3], ['z', 4], ['a',1]] 2 # 对每个列表的第一个值进行正常排序 3 print(sorted(Data, key=lambda x: x[0])) 4 # [['a', 1], ['x', 3], ['y', 2], ['z', 4]] 5 # 对每个列表的第一个值进行降序排序 6 print(sorted(Data, key=lambda x: x[0], reverse=True)) 7 # [['z', 4], ['y', 2], ['x', 3], ['a', 1]] 8 print(sorted(Data, key=lambda x: ord(x[0])*-1)) 9 # [['z', 4], ['y', 2], ['x', 3], ['a', 1]] 10 11 # 对每个列表的第二个值进行正常排序 12 print(sorted(Data, key=lambda x: x[1])) 13 # [['a', 1], ['y', 2], ['x', 3], ['z', 4]] 14 # 对每个列表的第二个值进行降序排序 15 print(sorted(Data, key=lambda x: x[1], reverse=True)) 16 # [['z', 4], ['x', 3], ['y', 2], ['a', 1]] 17 print(sorted(Data, key=lambda x: x[1]*-1)) 18 # [['z', 4], ['x', 3], ['y', 2], ['a', 1]]
多重排序:
# - 排序规则 # - 先按照书籍编号降序排序 # - 再按照书名正序排序 # - 再按照年份降序排序 number = { "test": "B", "helloworld": "A", "Little price": "C", "sg": "A", "rb": "A" } contents = """2017,126,test 2017,110,helloworld 2017,152,Little price 2017,98,sg 2017,89,rb 2018,116,test 2018,98,helloworld 2018,176,Little price 2018,79,sg 2018,90,rb 2019,122,test 2019,102,helloworld 2019,187,Little price 2019,102,sg 2019,103,rb""" Dts = [x.split(",") for x in contents.splitlines()] result = sorted(Dts, key=lambda x: (ord(number[x[2]]) * -1, x[2], int(x[0]) * -1)) # 打印结果 for x in result: print(number[x[2]], *x, sep="\t") """ C 2019 187 Little price C 2018 176 Little price C 2017 152 Little price B 2019 122 test B 2018 116 test B 2017 126 test A 2019 102 helloworld A 2018 98 helloworld A 2017 110 helloworld A 2019 103 rb A 2018 90 rb A 2017 89 rb A 2019 102 sg A 2018 79 sg A 2017 98 sg """
itemgetter与attrgetter模块的使用
from operator import itemgetter student_tuples = [ ('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10) ] # 按照索引为2的数据倒序排序 print(sorted(student_tuples, key=itemgetter(2), reverse=True)) # [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] # 多排排序: 先按照索引为1,再按照索引为2排序 print(sorted(student_tuples, key=itemgetter(1, 2))) # [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
from operator import attrgetter class Student: def __init__(self, name, grade, age): self.name = name self.grade = grade self.age = age def __repr__(self): return repr((self.name, self.grade, self.age)) student_tuples = [ Student('john', 'A', 15), Student('jane', 'B', 12), Student('dave', 'B', 10) ] # 按page排序 print(sorted(student_tuples, key=attrgetter("age"))) # [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] # 先按grade,再按age print(sorted(student_tuples, key=attrgetter("grade", "age"))) # [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]