5 Python 基础: 高阶函数学习实践
- 2019 年 10 月 4 日
- 筆記
目录
5 Python 基础: 高阶函数学习实践,共有 1 部分:
- 高阶函数
高阶函数
编写高阶函数,就是让函数的参数能够接收别的函数。
变量可以指向函数
以Python内置的求绝对值的函数abs()为例,调用该函数用以下代码:abs(-10)
什么是函数
函数本身也可以赋值给变量,即:变量可以指向函数,函数名其实就是指向函数的变量
print(abs(-1)) print(abs) x = abs(-1) print x f = abs print(f) print(f(-1)) # 结果: 1 <built-in function abs> 1 <built-in function abs> 1
print(abs(-1)) abs = 2 print(abs(-1)) # 结果: 1 TypeError: 'int' object is not callable
什么是高阶函数
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
def fun(x, y, f): print(f(x), f(y)) fun(1, -2, abs) # 结果: 1 2
内置高阶函数
map函数
map( ) 函数接收两个参数,一个是函数,一个是序列, map 将传入的函数依次作用到序列的每个元素,并把结果作为新的 list 返回。
def fun(x): return x * x print(map(fun, range(5))) # 结果: [0, 1, 4, 9, 16] ------------------------------------- print(map(str, [1, 2, 3])) # 结果: ['1', '2', '3']
reduce函数
reduce把一个函数作用在一个序列x1, x2, x3…上,这个函数必须接收两个参数,reduce 把结果继续和序列的下一个元素做累积计算。
def add(x, y): return x + y print(reduce(add, range(5))) # 结果: 10
其实其运行过程为:add(add(add(add(0+1)+2)+3)+4)=10
综合编程:写出把 str 转换为 int 的函数(eg:’12345’–12345)
def fun(N): return {"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9}[N] def fun1(x, y): return x * 10 + y print(reduce(fun1,map(fun,"12345"))) # 结果: 12345
filter函数
filter( ) 也接收一个函数和一个序列。和 map( ) 不同的时,filter( ) 把传入的函数依次作用于每个元素,然后根据返回值是 True还是 False 决定保留还是丢弃该元素
在一个 list 中,删掉偶数,只保留奇数:
def fun(n): return n % 2 == 1 print(filter(fun,range(5))) # 结果: [1, 3]
sorted函数
排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。通常规定如下:
x < y, return -1 x == y, return 0 x > y, return 1 ---------------------------- print(sorted([3, 1, 2])) print(sorted([3, 1, 2], reverse=True)) # 结果: [1, 2, 3] [3, 2, 1]
排序数字字符
li = ['2', '1', '4', '3'] print(sorted(li, key=int)) # 结果: ['1', '2', '3', '4']
匿名函数
• 当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。
• 关键字 lambda 表示匿名函数,冒号前面的 x 表示函数参数。
print(map(lambda x: x * x, [1, 2, 3, 4])) def fun(x): return x * x print(map(fun, [1, 2, 3, 4])) # 结果: [1, 4, 9, 16] [1, 4, 9, 16]
• 匿名函数有只能有一个表达式,不用写 return ,返回值就是该表达式的结果。
• 因为匿名函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数;
f = lambda x: x * x print(f) print(f(3)) # 结果: <function <lambda> at 0x7fde80eb7938> 9
• 把匿名函数作为返回值返回。
def fun(x, y): return lambda: x * x + y * y print(fun(1, 2)) f = fun(1, 2) print(f()) # 结果: <function <lambda> at 0x7f5c2942a9b0> 5
传入多个参数:
f = lambda x,y =1,*args,**kwargs :(x*y,args,kwargs) print(f(2,4,5,a=1,b=5)) # 结果: (8, (5,), {'a': 1, 'b': 5})
练习
1. (华为机试练习)
题目描述:数据表记录包含表索引和数值,请对表索引相同的记录进行合并,即将相索引的数值进行求和运算,输出按照key值升序进行输出。
– 输入描述:先输入键值对的个数,然后输入成对的index和value值,以空格隔开
– 输出描述:输出合并后的键值对(多行)
– 示例1:
输入
4 0 1 0 2 1 2 3 4
输出
0 3 1 2 3 4
脚本:
d = dict() Num = input("please input Num: ") for i in range(Num): N = raw_input("please input index and value: ") if d.has_key(N.split()[0]): New = str(int(d[N.split()[0]]) + int(N.split()[1])) d.pop(N.split()[0]) d.setdefault(N.split()[0], New) else: d.setdefault(N.split()[0], N.split()[1]) for j, k in sorted(d.items()): print(j, k)
2. 题目描述
现在IPV4下用一个32位无符号整数来表示,一般用点分方式来显示,点将IP地址分成4部分,每个部分为8位,表示成一个无符号整数(因此不需要用正号出现),10.137.17.1,是我们非常熟悉的IP地址,一个IP地址串中没有空格出现(因为要表示成一个32数字)。现在需要你用程序来判断IP是否合法。
输入描述:输入一个ip地址
输出描述:返回判断的结果YES or NO
示例1:
输入: 10.138.15.1
输出: YES
脚本:
IP = raw_input("please input IP: ") for i in IP: if not (i.isdigit() or i =="."): print("NO") exit(1) else: if len(IP.split(".")) == 4: for j in range(4): if int(IP.split(".")[j])>=0 and int(IP.split(".")[j])<=255: print("YES") exit() else: print("NO") exit(1) else: print("NO") exit(1)
3.函数式编程考察
用 filter()进行函数式编程,写一段代码来给出一个年份的列表并返回一个只有闰年的列表列表解析式实现方式呢?
def fun(N): if (N % 400 == 0) or (N % 4 == 0 and N % 100 != 0): return True else: return False Year = raw_input("please input Year: ") li = [] for i in Year: if not (i.isdigit() or i.isspace()): print("input Error!!!") exit(1) for j in Year.split(): li.append(int(j)) li = list(set(li)) print(filter(fun, li))
4.携程旅行网
给定一个整型数组,将数组中所有的”0”移到末尾,非”0”项保持顺序不变在原始数组上进行操作,勿创建新的数组
输入
第一行是数组长度 后续每一行是数组的第一条记录
输出
调整后的数组内容
样例输入
4 0 7 0 2
样例输出
7 2 0 0
array = [1, 0, 4, 0, 3, 2, 0, 1] print(sorted(array, key=lambda x: 1 if x == 0 else 0)) # 结果: [1, 4, 3, 2, 1, 0, 0, 0]