函数式编程虽然也可以归结到面向过程的程序设计,但其思想更接近于数学计算
函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数
Python对函数式编程提供部分支持,由于Python允许使用变量,因此,Python不是纯函数式编程语言
高阶函数
在Python中,函数本身也可以赋值给变量的,即变量可以指向函数,函数名也是变量
既然变量可以指向函数,函数的参数能接受变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数
def add(x, y, f):
return f(x) + f(y)
a = -2
b = -9
c = abs
print(add(a, b, c))
11
Process finished with exit code 0
把函数作为参数传入,这样的函数称之为高阶函数,函数式编程就是指这种高度抽象的编程范式
map/reduce
Python中内置了map()和reduce()函数
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每一个元素,并把结果作为新的Iterator返回
def f(x):
return x * x
result = map(f, [1, 2, 3, 4])
print(list(result))
[1, 4, 9, 16]
Process finished with exit code 0
将list中的数字全部转换成字符串
print(list(map(str, [1, 2, 3, 4])))
reduce()函数把一个函数作用在一个序列上,这个函数必须接收两个参数,reduce继续把结果和序列的下一个元素做计算
from functools import reduce
def add(x, y):
return x + y
nums = list(range(1, 101))
print(reduce(add, nums))
5050
Process finished with exit code 0
filer
filter()函数用于过滤序列,其接收一函数和一个序列,filer把传入的函数依次作用于每个元素,根据返回值是True还是False决定保留还是丢弃该元素
"""
用filter求素数
埃氏筛法
"""
def get_odd_iter():
"""
生成一个从3开始的奇数序列
:return:
"""
n = 1
while True:
n += 2
yield n
def f(y):
"""
筛选函数
:param y:
:return:
"""
return lambda x: x % y > 0
def primes():
yield 2
it = get_odd_iter()
while True:
i = next(it)
yield i
it = filter(f(i), it)
# 打印10000以内的素数
for j in primes():
if j < 10000:
print(j)
else:
break
sorted
Python内置的sorted()函数可以对list进行排序,此外,sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义排序
eg:对一个list按照绝对值进行排序
print(sorted([36, -8, 1, 12, 0, -21], key=abs))
[0, 1, -8, 12, -21, 36]
Process finished with exit code 0
key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序
eg:字符串忽视大小写排序
print(sorted(['Tom', 'martin', 'Sam', 'Au'], key=str.lower))
['Au', 'martin', 'Sam', 'Tom']
Process finished with exit code 0
sorted()函数也是一个高阶函数,用sorted()排序的关键在于实现一个映射函数
返回函数
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回
def lazy_sum(*args):
def get_sum():
result = 0
for i in args:
result += i
return result
return get_sum
f = lazy_sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
print(f())
55
Process finished with exit code 0
我们在函数lazy_sum中又定义了函数get_sum,并且内部函数可以引用外部函数的参数和局部变量,当外部函数返回get_sum函数时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力
返回闭包时要注意:返回函数不要引用任何循环变量,或者后续会发生变化的变量
匿名函数
关键字lambda表示匿名函数,冒号前面的x表示函数的参数
匿名函数只能有一个表达式,不用写return,返回值就是该表达式的结果
print(list(map(lambda x: x * x, [2, 4, 6])))
print((lambda x: x ** 3)(2))
[4, 16, 36]
8
Process finished with exit code 0