Python自学笔记---13.高阶函数

高阶函数

本节部分内容借鉴廖雪峰老师的的博客

1.变量可以指向函数

无论是在C语言还是在Python中函数都可以有一个返回值,来返回整个函数运算的结果。

f = str(159) #函数的返回值赋值给变量
print(f)

那么在C语言中还有一种叫做函数指针,就是把函数的地址赋值给一个变量。在C语言中在调用函数的时候需要使用间接寻址符号 * 来寻址。龟叔在玩Python的时候也是用的C语言去实现底层的东西。所以在Python中也有类似的这么一个东西。(函数的名称可以保存在一个变量中,后续可以通过这个变量来调取该函数)当然,Python中是没有指针这么一说的,现在回想起那被指针支配的恐惧,手心的汗都冒出来了。
在python中是可以将函数本身赋值给一个变量的,如下实例

f = str
print(f)
print(str)
#打印的结果如下:
<class 'str'>
<class 'str'>

虽然我暂时还没有找出合适的打印函数地址的方法,但是上述的方法却足以说明咱们的疑虑。

d = abs #abs函数的功能这里就不细说了
print(d(-10))

2.传入函数

函数的参数能接收变量,上面又讲了变量可以指向函数,那么是不是我们可以先将一个函数名赋值给一个变量,再将这个变量传值给另外的一个函数呢?答案是确切的,而且这样的函数被称之为“高阶函数”

def add(f, x, y):
    return f(x) + f(y)

x = -5
y = 9
f = abs
ret = add(f, x, y)
print(ret)

2.1 map函数

map(function, iterable, …)
function – 函数
iterable – 一个或多个序列
注意:map函数返回的序列是一个新生成的序列而并不会破坏原有的序列

实例:

def f(x):
    return x ** x
list1 = [1, 2, 3, 4, 5, 6, 7]

print(list(map(f, list1)))

这里要说明的一点是,map()传入的第一个参数是f,即函数对象本身。由于结果list1是一个Iterator,Iterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list。

2.2 reduce函数

reduce(function, iterable[, initializer])
function – 函数,这个函数必须接收两个参数
iterable – 可迭代对象
initializer – 可选,初始参数
综述:函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果
效果就是:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

实例:

from functools import reduce
def add(x, y):
    return x + y

a = reduce(add, [1, 3, 5, 7, 9])
print(a)

2.3 filter 函数

filter(function, iterable)
function – 判断函数
iterable – 可迭代对象
filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素,最后将返回 True 的元素放到新列表中

def is_odd(n):
    return n % 2 == 1

newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(newlist)

2.4 sorted 函数

首先来说sorted与sort的区别

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

sorted语法:

sorted(iterable[, key[, reverse]]])
iterable – 可迭代对象
cmp – 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0(python3中已经没有了cmp函数了)
key – 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序
reverse – 排序规则,reverse = True 降序 , reverse = False 升序(默认)

a = [6, 8, 9, 10, 2, 6, 11]
b = sorted(a)  # 保留原列表

print(a)
print(b)

#其打印结果为
[6, 8, 9, 10, 2, 6, 11]
[2, 6, 6, 8, 9, 10, 11]

接下来看一下sorted的参数应用

L=[('b',2),('a',1),('c',3),('d',4)]
L = [('b',2),('a',1),('c',3),('d',4)]
L1 = sorted(L, key=lambda x:x[1]) #使用参数key
L2 = sorted(L, key=lambda x:x[1], reverse = True)
print(L1)
print(L2)
#其打印结果为
[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
[('d', 4), ('c', 3), ('b', 2), ('a', 1)]

3. 返回函数

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回

def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum

当我们调用lazy_sum()时,返回的并不是求和结果,而是求和函数:

f1 = lazy_sum(1, 3, 5, 7, 9)
f2 = lazy_sum(1, 3, 5, 7, 9)
print(f1)
#打印结果为
.sum at 0x0000025CFBD53E18>

#继续扩展上述代码
print("1",f1())
print("2",f2())
#其打印结果为
1 25
2 25

在这个例子中,我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。

请再注意一点,当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数,既就是 f1 != f2

总结

-本节算是一个回顾,在我学习了廖雪峰老师的课程后做的总结,其中部分实例,不是我亲自编写,但确确实实手动敲了一遍。
- 首先学习了函数的一个特性,变量可以被看做是一个“指针”,指向一个函数,既把一个函数的地址赋值给一个变量。在后学讲述了这个变量作为参数如何被传入另外一个函数。
- 然后我们对几个常见的高阶函数做了简单的了解学习
- 在结尾部分,学习了一个函数作为另一个函数的返回值,并且要知道返回时,只是返回这个函数,而并非这个函数的运算结果。相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序。

你可能感兴趣的:(Python自学笔记)