变量可以指向函数
>>> f(-10)
10
说明变量 f 现在已经指向了 abs 函数本身。 直接调用 abs() 函数和调用变量 f() 完全相同。
函数名也是变量
函数名其实就是指向函数的变量!对于 abs() 这个函数,完全可以把函数名 abs 看成变量, 它指向一个可以计算绝对值的函数!
>>> abs = 10
>>> abs(-10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
把 abs 指向 10 后, 就无法通过 abs(-10) 调用该函数了!因为 abs 这个变量
已经不指向求绝对值函数而是指向一个整数 10 !
传入函数
既然变量可以指向函数, 函数的参数能接收变量, 那么一个函数就可以接收另一个函数作为参数, 这种函数就称之为高阶函数。
一个最简单的高阶函数:
def add(x, y, f):
return f(x) + f(y)
>>> add(-5, 6, abs)
11
把函数作为参数传入, 这样的函数称为高阶函数, 函数式编程就是指这种高度抽象的编程范式。
map/reduce
Python内建了 map() 和 reduce() 函数。
map() 函数接收两个参数, 一个是函数, 一个是 Iterable , map 将传入的函数依次作用到序列的每个元素, 并把结果作为新
的 Iterator 返回。
现在, 我们用Python代码实现:
def f(x):
return x * x
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce 把一个函数作用在一个序列 [x1, x2, x3,...] 上, 这个函数必须接收两个参数, reduce 把结果继续和序列的下一个元素
做累积计算, 其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
比方说对一个序列求和, 就可以用 reduce 实现:
from functools import reduce
def add(x, y):
return x + y
>>> reduce(add, [1, 3, 5, 7, 9])25
写一个 prod() 函数, 可以接受一个list并利用 reduce() 求积:def prod(L):
from functools import reduce
def subprod(x,y):
return int(x) * int(y)
return reduce(subprod,L)
>>>print('3*5*7:',prod([3,5,7]))
3*5*7: 105
filter
Python内建的 filter() 函数用于过滤序列 .
和 map() 类似, filter() 也接收一个函数和一个序列。 和 map() 不同的时, filter() 把传入的函数依次作用于每个元素, 然后根据返回值是 True 还是 False 决定保留还是丢弃该元素。
例如, 在一个list中, 删掉偶数, 只保留奇数, 可以这么写:
def is_odd(n):
return n % 2 == 1
>>>list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))# 结 果 : [1, 5, 9, 15]
filter() 函数返回的是一个 Iterator , 也就是一个惰性序列, 所以要 强 迫 filter() 完成 计 算 结 果, 需要用 list() 函数 获 得所有 结 果并返回 list 。
filter() 的作用是从一个序列中筛出符合条件的元素。 由于 filter() 使用了惰性计算, 所以只有在取 filter() 结果的时候, 才会真正筛选并每次返回下一个筛出的元素。
sorted :排序算法
Python内置的 sorted() 函数就可以对list进行排序:
>>> sorted([36, 5, -12, 9, -21])
[-21, -12, 5, 9, 36]
我们给 sorted 传入key函数, 即可实现忽略大小写的排序:
sorted() 函数也是一个高阶函数, 它还可以接收一个 key 函数来实现自定义的排序, 例如按绝对值大小排序:
>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]
我
们
再看一个字符串排序的例子:
>>> sorted(['bob', 'about', 'Zoo', 'Credit'])
['Credit', 'Zoo', 'about', 'bob']
默
认
情况下,
对
字符串排序, 是按照
ASCII
的大小比
较
的, 由于
'Z' < 'a'
,
结
果, 大写字母
Z
会排在小写字母
a
的前面。
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
['about', 'bob', 'Credit', 'Zoo']
要
进
行反向排序, 不必改
动
key
函数, 可以
传
入第三个参数
reverse=True
:
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
['Zoo', 'Credit', 'bob', 'about']
用 sorted() 对列表分别按名字排序:
>>>L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
>>>L2 = sorted(L)
>>>print(L2)
[('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88),]
用
sorted()
对
列表分
别
按成绩排序:
>>>L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
>>>sorted(L,key = lambda l:l[1])
>>>print(L2)
[('Bart', 66), ('Bob', 75), ('Lisa', 88), ('Adam', 92)]