Python函数式编程

函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。

函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!

Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。

一、高阶函数

函数本身也可以赋值给变量,即:变量可以指向函数。

函数名其实就是指向函数的变量

一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数

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

二、map

map()函数接收两个参数,一个是函数,一个是Iterablemap将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。

  >>> 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

reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算

  >>> from functools import reduce #对一个序列求和
  >>> def add(x, y):
  ...     return x + y
  ...
  >>> reduce(add, [1, 3, 5, 7, 9])
  25

四、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]

五、排序

Python内置的sorted()函数就可以对list进行排序,sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序

  >>> sorted([36, 5, -12, 9, -21], key=abs)
  [5, 9, -12, -21, 36]

高阶函数的抽象能力是非常强大的

  >>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
  ['Zoo', 'Credit', 'bob', 'about']

六、返回函数

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

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

返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

七、匿名函数

关键字lambda表示匿名函数,冒号前面的x表示函数参数。

  >>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
  [1, 4, 9, 16, 25, 36, 49, 64, 81]

Python对匿名函数的支持有限,只有一些简单的情况下可以使用匿名函数。

八、装饰器

在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。

在面向对象(OOP)的设计模式中,decorator被称为装饰模式。OOP的装饰模式需要通过继承和组合来实现,而Python除了能支持OOP的decorator外,直接从语法层次支持decorator。Python的decorator可以用函数实现,也可以用类实现。

decorator可以增强函数的功能,定义起来虽然有点复杂,但使用起来非常灵活和方便。

九、偏函数

当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。

博客内容用于记录自己学习后的收获,如有侵权请联系我删除
原文地址:https://www.cnblogs.com/ptxiaochen/p/13629453.html