python高阶函数map reduce filter sorted_Python 高阶函数map、reduce、filter、sorted

今天和大家聊一聊Python 中的高阶函数:map、reduce、filter、sorted

首先了解一下什么是高阶函数,

高阶函数 就是让函数的参数能够接受别的函数,比如:

1 defadd(x, y, f):2 return f(x) +f(y)3

4 result = add(-5, 6, abs)5 print(result) #11

再比如:

1 list1 = [1, 2, 3, 4, 5, 6]2 list2 = [32, 11, 55, 46, 89, 43]3 defadd_total(l1, l2, fun):4 return fun(l1) +fun(l2)5

6 result =add_total(list1, list2, min)7 print(result) #12

8 result =add_total(list1, list2, max)9 print(result) #95

那么Python 中这些高阶函数具体的作用是什么呢?不要着急,往下面看看

一、map 函数,接受两个参数,一个是函数,另一个是迭代对象Iterable ,将迭代对象Iterable 里面的每个元素作用到这个函数里面后,生成新的map 对象(是迭代器对象Iterator),并返回,比如:

1 deff_double(x):2 return 2 *x3

4 list1 = [1, 2, 3, 4, 5, 6]5 m =map(f_double, list1)6 #print(list(m)) # [2, 4, 6, 8, 10, 12]

7 print(m) # 注意这个map 函数返回的是一个map 对象,这个map 对象是一个迭代器对象,所以可以调用next() 函数,也可以去使用for 循环进行循环遍历

8 print(next(m)) #2 注意,需要注释上面的print(list(m))并重新运行,否则会报StopIteration 的错误

二、reduce 函数, 和map 函数一样接受两个参数,第一个是函数,第二个是序列Iterable ,不同是reduce 把结果继续和序列的下一个元素做累积运算,效果如下:

1 #reduce(fn, [x1, x2, x3, x4]) = fn(fn(fn(x1, x2), x3), x4)

2

3 defmultiple(x, y):4 return x * 10 +y5

6 from functools importreduce7 list1 = [1, 3, 5, 7, 9]8 r =reduce(multiple, list1)9 print(r) #13579

这个例子本身没多大用处,但是考虑到字符串str 也是一个序列,对上面的例子稍加改动,配合map()

就可以写出str 转换为int 的函数:

1 from functools importreduce2

3 DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4,4 '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}5 defmultiple(x, y):6 return x * 10 +y7

8 defchar2num(s):9 returnDIGITS[s]10

11 r = reduce(multiple, map(char2num, '2468'))12 print(r) # 2468

下面是廖老师出的几个问题,同学们可以思考一下,并参考一下我这边给出的代码,看看还有没有什么可以优化,或者我没考虑的地方,欢迎留言指导~

Q1.综合写一个不借助int() 函数,将字符串转换成数字的方法:

ContractedBlock.gif

ExpandedBlockStart.gif

1 from functools importreduce2

3 DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4,4 '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}5 defstr2num(s):6 m = map(lambdax: DIGITS[x], s)7 try:8 r = reduce(lambda x, y: x*10+y, m)9 exceptKeyError:10 print('请输入纯数字的字符串!')11 else:12 returnr13

14 result = str2num('3234cc4')15 print(type(result))16 print(result)17

18 #请输入纯数字的字符串!

19 #

20 #None

21

22 result2 = str2num('32344')23 print(type(result2))24 print(result2)25

26 #

27 #32344

Q1

Q2.利用map() 函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写

ContractedBlock.gif

ExpandedBlockStart.gif

1 defnormalize(name):2 try:3 if notname.isalpha():4 return

5 exceptAttributeError:6 print("您输入的:{} 不是正确的姓名".format(name))7 else:8 returnname.capitalize()9 #result = str(name).capitalize()

10 #return result

11

12 L1 = ['adam', 'LISA', 'barT1', 123, 0, True, '123333', [23,11], (11, 33), "丽丽"]13 L2 = [x for x in map(normalize, L1) ifx]14 print('你输入的最终姓名名单为:{}'.format(L2))15

16

17 #您输入的:123 不是正确的姓名

18 #您输入的:0 不是正确的姓名

19 #您输入的:True 不是正确的姓名

20 #您输入的:[23, 11] 不是正确的姓名

21 #您输入的:(11, 33) 不是正确的姓名

22 #你输入的最终姓名名单为:['Adam', 'Lisa', '丽丽']

Q2

Q3.利用map 和reduce 编写一个str2float 的函数,比如把字符串‘123.456’ 转换成浮点数123.456

ContractedBlock.gif

ExpandedBlockStart.gif

1 defstr2float(s):2 i1, f1 =split_int_float(s)3 int_res =char2num(i1)4 float_res = char2num(f1) / 10**len(f1)5 return int_res +float_res6

7 defsplit_int_float(s):8 #以小数点为分隔区,返回整数部分和小数部分

9 str_int, str_float = s.split('.')[0], s.split('.')[1]10 returnstr_int, str_float11

12 defchar2num(char):13 DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}14 from functools importreduce15 num = reduce(lambda x, y:x*10+y, map(lambdax:DIGITS[x], char))16 returnnum17

18

19 print('str2float(\'123.456\') =', str2float('123.456'))20 if abs(str2float('123.456') - 123.456) < 0.00001:21 print('测试成功!')22 else:23 print('测试失败!')24

25

26 #str2float('123.456') = 123.456

27 #测试成功!

Q3

三、filter 函数 也是接收一个函数和一个序列,filter()把传入的函数作用于序列的每个元素,然后根据返回值是True 还是False 决定保留还是丢弃该元素

1.比如把一个序列中的非字符串删掉,可以这么写:

1 defnot_empty(s):2 try:3 s.strip()4 exceptAttributeError:5 print('请输入字符串')6 else:7 return s ands.strip()8

9 list_filter = list(filter(not_empty, ['A', '', 'B', None, 'C', ' ', 'B C', 'VV', 123]))10 print(list_filter)11

12 #请输入字符串

13 #请输入字符串

14 #['A', 'B', 'C', 'B C', ' VV']

2.回数,值从左向右和从右向左读都是一样的数,如:12321,909,787,66266

1 defis_palindrome(n):2 return str(n) == str(n)[::-1]3

4 #backnum = filter(is_palindrome, range(1, 100))

5 backnum = filter(lambda x: str(x) == str(x)[::-1], range(1, 100))6

7 print('1~100的回数为:', list(backnum)) # 1~100的回数为: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99]

四、sorted 函数,可以对list 进行排序:list 的元素,可以是数值,直接比较大小,也可以是字母,会按照ASCII 码比较

注意,sorted 函数和 列表的sort() 方法是有区别的

sorted(list1), 对list1 进行排序,并作为一个新的列表返回,list1 不变

ist1.sort(), 对list1 本身进行排序,改变的将是list1

前面说了sorted 函数也是一个高阶函数,它可以接收一个参数key 来实现自定义排序,key 的值是别的函数,或者是匿名函数。例如按照绝对值大小排序:

1 list4 = [-1, 9, -6, 55, 33, -5]2 sort_list =sorted(list4)3 abs_list = sorted(list4, key=abs)4 print(sort_list) #[-6, -5, -1, 9, 33, 55]

5 print(abs_list) #[-1, -5, -6, 9, 33, 55]

6

7 list5 = ['bob', 'about', 'Zoo', 'Credit']8 res =sorted(list5)9 print(res) #['Credit', 'Zoo', 'about', 'bob']

默认情况下,对字符串排序,是按照ASCII 的大小比较的,由于 在ASCII 中 'Z' < 'a', 所以‘Z’会排在‘a’前面

忽略大小写的做法:

1 list5 = ['bob', 'about', 'Zoo', 'Credit']2 res_sort = sorted(list5, key=str.lower)3 print(res_sort) #['about', 'bob', 'Credit', 'Zoo']

反序排序列,不必动用key 函数,可以传入第三个参数reverse=True,如:

1 list5 = ['bob', 'about', 'Zoo', 'Credit']2 res_reverse_sort = sorted(list5, reverse=True)3 ignore_reverse_sort = sorted(list5, key=str.lower, reverse=True)4 print(res_reverse_sort) #['bob', 'about', 'Zoo', 'Credit']

5 print(ignore_reverse_sort) #['Zoo', 'Credit', 'bob', 'about']

sorted 函数的最最常用的场景,也是面试中经常会遇到的问题,给一个元素是元祖的列表按照元素第二个元素排序,或者是对一个字典的Value 进行排序,如下:

1 D1 = {'Bob': 75, 'Adam': 92, 'Bart': 66, 'Lisa': 88}2 L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]3 D2 = {'name': 'Lucy', 'age': 18, 'id': '110', 'sex': 'women'}4 print(sorted(L, key=lambda x: x[0].lower())) #按照人名排序,(不分大小写)

5 print(sorted(D1.items(), key=lambda x: x[1])) #相当于先把D1 转换成L ,然后进行第7 行代码

6 print(sorted(D2.items(), key=lambda x: x[0].lower())) #按照字典的K 排序,不分大小写

7 print(sorted(L, key=lambda x: x[1])) #将L 按照成绩从小到大排序

8 print(sorted(L, key=lambda x: -x[1])) #将L 按照成绩从大到小排列

9

10

11

12 [('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]13 [('Bart', 66), ('Bob', 75), ('Lisa', 88), ('Adam', 92)]14 [('age', 18), ('id', '110'), ('name', 'Lucy'), ('sex', 'women')]15 [('Bart', 66), ('Bob', 75), ('Lisa', 88), ('Adam', 92)]16 [('Adam', 92), ('Lisa', 88), ('Bob', 75), ('Bart', 66)]

至此,这四个Python 比较常用的高阶函数介绍完毕了,希望能给大家的学习带来一定的帮助

参考:高阶函数-廖雪峰的官方网站:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014317849054170d563b13f0fa4ce6ba1cd86e18103f28000

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值