【python】38_高级特性之内置高阶函数

【摘要】函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数! Python对函数式编程提供部分支持。把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。

1.map()

map() 会根据提供的函数对指定序列做映射
第一个参数接受一个函数名,后面的参数接受一个或多个可迭代的序列,返回的是一个集合。
在这里插入图片描述
例如:我们要对传入的5个数字进行排序。首先要有一个列表存储这输入的五个数字,而列表对这五个数字是以字符串的格式排序,如果需要排序,首先要依次转换成为int型,再使用sorted方法排序。

nums = [input() for i in range(5)]
print(nums)
# 使用for循环将数值转为整形
int_nums = [int(num) for num in nums]
print(sorted(int_nums))

在这里插入图片描述
我们知道map()会根据提供的函数对执行序列做映射,那对这样的需求,我们就可以使用map(int,nums),即对nums这个序列执行int函数来做映射。

nums = [input() for i in range(5)]
print(nums)
# 使用map转换数值为整形
map_num = map(int, nums)
sorted_num  = sorted(map_num)
print(sorted_num)

在这里插入图片描述
判断我们传入的map_num是否为可迭代对象

from collections.abc import  Iterable
print(isinstance(map_num, Iterable))

在这里插入图片描述

当seq多于一个时,map可以并行(注意是并行)地对每个seq执行如下图所示的过程:
在这里插入图片描述
例如:我们定义一个函数line,接收两个参数,返回这两个参数的二元一次方程。

def line(num1, num2):
    return  num1 *10 + num2

再生成两个序列

nums1 = range(2, 6)
nums2 = range(1, 6)
# nums1 = 2   3  4   5
# nums2 = 1   2  3   4  5

使用map()函数对这两个序列进行line函数的映射。

result = map(line, nums1, nums2)
print(list(result))

在这里插入图片描述
总结:
map的传递,函数名可以是内置函数、匿名函数、自定义函数。
map的传递,可迭代对象可以是多个序列。

2. reduce()

reduce() 函数会对参数序列中元素进行累积。
第一个参数接受一个函数名,后面的参数接受一个或多个可迭代的序列,返回的是一个结果。
在这里插入图片描述
【注】py2中reduce是内置的高阶函数, py3需要导入functools模块
例如:对序列中的数值求和

# 求两个数值和的匿名函数定义;
add = lambda x, y: x + y
result = reduce(add, [1, 2, 3, 4])
print(result)

在这里插入图片描述
reduce的工作机制: result=add(add(add(1, 2), 3), 4)

再例如求10的阶乘:

result = reduce(lambda  x, y:x*y, range(1, 10))
print(result)

在这里插入图片描述

3.filter()

filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
第一个参数接受一个函数名,后面的参数接受一个或多个可迭代的序列,返回的是一个序列。
在这里插入图片描述
例如:求100以内的所有偶数。当然最简单还是range(0, 101, 2)
如果用filter()函数,我们就需要定义一个判断偶数的函数,将其作为参数传给filter()。

def is_odd(num):
    """
    判断是否为偶数, 返回值为Bool类型
    :param num:
    :return:
    """
    return  num %2 ==0

将序列和自定义is_odd函数传入

odd_nums = filter(is_odd, range(0,101))
print(list(odd_nums))

在这里插入图片描述
截图不完全。
当然也可以直接将is_odd函数写成匿名函数形式作为参数传入

odd_nums = filter(lambda  num: num%2==0, range(0, 101))
print(list(odd_nums))

再看几个例子:
1.获取100以内能被3或者5整除的所有数

result1 = filter(lambda num: num % 3 == 0 or num % 5 == 0, range(100))
print(list(result1))

在这里插入图片描述
2.获取2000-2999年,所有的闰年

is_leap = lambda year: (year % 4 == 0 and year % 100 !=0) or year % 400 == 0
result2 = filter(is_leap, range(2000, 3000))
print(list(result2))

在这里插入图片描述
3.获取1000内容所有的素数

def is_prime(num):
    """判断是否为素数"""
    if num < 2:
        return  False
    for i in range(2, num):
        if num %i == 0:
            return  False
    else:
        return  True

result3 = filter(is_prime, range(1001))
print(list(result3))

在这里插入图片描述

4.max/min/sorted

goods = [
    ["苹果", 2, 1000],
    ["电脑", 9999, 300],
    ["手机", 5999, 790]
]

top_price = max(goods,  key=lambda x: x[1])
print(top_price)
print("价格最高的商品名称: ", top_price[0])

low_count = min(goods, key=lambda x: x[2])
print("库存量最少的商品名称: ", low_count[0])

high_count = max(goods, key=lambda x: x[2])
print("库存量最多的商品名称: ", high_count[0])

在这里插入图片描述
sorted() 函数对所有可迭代的对象进行排序操作。返回重新排序的列表。
sorted(iterable, key=None, reverse=False)
key: 主要是用来进行比较的元素,只有一个参数,
reverse: 排序规则,True 降序 ,False 升序(默认)。

例如:携程有个笔试题,要求将所有的偶数移动到前面, 将所有的奇数移动到最后
用sorted(),一行代码就搞定啦。

li =list(range(10))
sorted_li = sorted(li, key=lambda  num: 0 if num%2==0 else 1)
print(sorted_li)

在这里插入图片描述
【补充】python排序sort()和sorted()的区别是什么?

  1. 排序对象不同: sort 是应用在list 上的方法,sorted 可以对所有可迭代的对象进行排序操作
  2. 返回值不同:
    list 的 sort 方法返回的是对已经存在的列表进行操作,无返回值,
    内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。

提出一个问题:
在这里插入图片描述
将result再转换成字典后,d为什么为空呢?
因为在python3中,range、map、zip、reduce等生成的都是生成器对象,一边循环一边计算,将执行完了也就没有了(range除外)。而在python2中,生成的是列表,并非生成器对象,很明显python3对此做了优化,节省了内存空间。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值