1、一等公民
函数在 Python 是一等公民(First-Class Object)
函数也是对象,是可调用对象
函数可以作为普通变量,也可以作为函数的参数、返回值
2、高阶函数(High-order Function)
数学概念 y=f(g(x))
在数学和计算机科学中,高阶函数应当是至少满足下面一个条件的函数:
接受一个或多个函数作为参数
输出一个函数
# 高阶函数,例1: def counter(base): def inc(step=1): # 局部变量 nonlocal base base += step return base return inc # 局部变量 inc,每次赋值即重新定义 c1 = counter(5) c2 = counter(5) print(c1(), c2()) # 6 6 print(c1() == c2()) # True,函数对象的返回值相等 print(counter(5) == counter(5)) # False,函数每次调用都不一样
# 高阶函数,例2:
def inc(step=1): return step def counter(): return inc # 返回全局变量 inc c1 = counter() c2 = counter() print(c1 == c2) # True,因为全局变量 inc 不消亡
3、自定义 sort 函数
仿照内建函数 sorted,请自行实现一个 sort 函数(不用使用内建函数),能够为列表元素排序。
思考:通过练习,思考 sorted 函数的实现原理,map、filter 函数的实现原理。
思路:
内建函数 sorted 函数,它返回一个新的列表,可以设置升序或降序,可以设置一个用于比较的函数(自定义函数也要实现这些功能)
新建一个列表,遍历原列表,和新列表中的当前值依次比较,决定带插入数插入到新列表的什么位置。
实现1:实现升序和倒序
def sort(iterable): # 例:[4, 3, 6] target = [] for x in iterable: for i, y in enumerate(target): # [4] if x < y: # 被插入值小于当前索引值,insert 插入(升序),即当 x > y 时倒序 target.insert(i, x) break # 找到插入位置,结束当前循环 else: target.append(x) return target print(sort([4, 3, 6]))
实现2:实现 reverse
def sort(iterable, *, reverse=False): # 设定 reverse 缺省值为 False,不反转 target = [] for x in iterable: for i, y in enumerate(target): order = x > y if reverse else x < y # 通过 reverse 关键字传参,实现 升序、逆序 if order: target.insert(i, x) break else: target.append(x) return target print(sort([4, 3, 6], reverse=True)) # [6, 4, 3]
实现3:实现 key
def sort(iterable, *, key, reverse=False): target = [] for x in iterable: for i, y in enumerate(target): order = key(x) > key(y) if reverse else key(x) < key(y) # key() if order: target.insert(i, x) break else: target.append(x) return target print(sort([4, 3, '3', 6], reverse=True, key=int)) # [6, 4, 3, '3']
实现4:实现 key 的缺省值,key=None
def sort(iterable, *, key=None, reverse=False): target = [] for x in iterable: for i, y in enumerate(target): x = key(x) if key else x y = key(y) if key else y # 不符合(转换后的结果只是用来比较大小的,不改变最后生成的列表中的元素本身)! # 而且 x 重复计算! order = x > y if reverse else x < y if order: target.insert(i, x) break else: target.append(x) return target print(sort([4, 3, '3', 6], reverse=True, key=str)) # ['6', 4, '3', '3']
# 再改进! def sort(iterable, *, key=None, reverse=False): target = [] for x in iterable: cx = key(x) if key else x # 转换后的结果只是用来比较大小的,不改变最后生成的列表中的元素本身 for i, y in enumerate(target): cy = key(y) if key else y order = cx > cy if reverse else cx < cy if order: target.insert(i, x) break else: target.append(x) return target print(sort([4, 3, '3', 6], reverse=True, key=str)) # [6, 4, 3, '3']
4、内建高阶函数
排序 sorted
定义:sorted(iterable, *, key=None, reverse=False) => list
''' sorted() # 返回新列表 list.sort() # 就地修改 ''' lst = [1, 4, 2, 6, 3] print(sorted(lst, key=lambda x : 7-x)) # 升序,key=lambda x : 7-x,影响排序结果 lst.sort(reverse=True, key=lambda x : 7-x) # 降序,key=lambda x : 7-x,影响排序结果 print(lst) # 执行结果: [6, 4, 3, 2, 1] [1, 2, 3, 4, 6]
映射 map
g = list(map(lambda x : x+1, range(1, 6))) print(g) # [2, 3, 4, 5, 6] g1 = { i:(i, i+1) for i in map(lambda x : x+1, range(1, 6))} print(g1) # {2: (2, 3), 3: (3, 4), 4: (4, 5), 5: (5, 6), 6: (6, 7)} g2 = dict(map(lambda x : (x+1, (x+1, x+2)), range(1, 6))) # 二元组 print(g2) # {2: (2, 3), 3: (3, 4), 4: (4, 5), 5: (5, 6), 6: (6, 7)} g3 = dict(zip(range(2, 7), map(lambda x : (x, x+1), range(2, 7)))) print(g3) # {2: (2, 3), 3: (3, 4), 4: (4, 5), 5: (5, 6), 6: (6, 7)} g4 = dict(map(lambda x, y : [x, y], 'abcde', range(10))) print(g4) # {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4}
过滤 filter
# if element: yield element # 如果这个元素,则返回这个元素 print(filter(None, range(10))) # 惰性对象 print(list(filter(None, range(10)))) # [1, 2, 3, 4, 5, 6, 7, 8, 9] print(list(filter(None, range(-5, 5)))) # [-5, -4, -3, -2, -1, 1, 2, 3, 4] # if fn(element): yield element print(list(filter(lambda x : True, range(10)))) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print(list(filter(lambda x : None, range(10)))) # [] print(list(filter(lambda x : 0, range(10)))) # [] # 如果 x%3==0,则为 True print(list(filter(lambda x : x%3==0, [1, 9, 55, 150, -3, 78, 28, 123]))) # [9, 150, -3, 78, 123]