< 笔记 > Python

来源:互联网 发布:wow.js算是预加载么 编辑:程序博客网 时间:2024/06/14 02:43

05 Python 函数式编程

By Kevin Song

  • 05-01 高阶函数
    • 05-01-01 map/reduce
    • 05-01-02 filter
    • 05-01-03 sorted
  • 05-02 返回函数
  • 05-03 匿名函数
  • 05-04 装饰器
  • 05-05 偏函数

函数式编程:一种抽象程度很高的编程范式

特点:允许把函数本身作为参数传入另一个函数,返回一个函数

05-01 高阶函数(Higher-order function)

变量可以指向函数

函数调用

>>> abs(-10)10

函数本身

>>> abs<built-in function abs>

函数返回值 赋给 变量

>>> x = abs(-10)>>> x10

函数本身 赋给 变量

>>> f = abs>>> f<built-in function abs>

函数名也是变量

abs() 中函数名 abs 也是变量,它指向一个可以计算绝对值的函数

把abs指向10后,就无法通过abs(-10)调用该函数,因为abs这个变量已经不指向求绝对值函数而是指向一个整数10

>>> abs = 10>>> abs(-10)Traceback (most recent call last):  File "<stdin>", line 1, in <module>TypeError: 'int' object is not callable

高阶函数

高阶函数: 一个函数作为参数传递给另一个函数

def add(x, y, f):    return f(x) + f(y)
>>> add(-5, 6, abs)11

计算过程

x = -5y = 6f = absf(x) + f(y) ==> abs(-5) + abs(6) ==> 11return 11

05-01-01 map/reduce

map() 函数

  • map() 函数接收两个参数,一个是函数,一个是Iterable
  • map将传入的函数依次作用到序列的每个元素,并把结果作为新的惰性序列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]

把这个list所有数字转为字符串

>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))['1', '2', '3', '4', '5', '6', '7', '8', '9']

reduce() 函数

  • reduce() 函数接收两个参数,一个是接收两个参数的函数,一个是Iterable
  • reduce 把第一第二个元素的计算结果继续和序列的下一个元素做计算
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

把序列[1, 3, 5, 7, 9]变换成整数13579

>>> from functools import reduce>>> def fn(x, y):...     return x * 10 + y...>>> reduce(fn, [1, 3, 5, 7, 9])13579

map()和reduce()组合

把str转换为int的函数

>>> from functools import reduce>>> def fn(x, y):...     return x * 10 + y...>>> def char2num(s):...     return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]...>>> reduce(fn, map(char2num, '13579'))13579

05-01-02 filter

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

在一个list中,删掉偶数,只保留奇数

def is_odd(n):    return n % 2 == 1list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))# 结果: [1, 5, 9, 15]

一个序列中的空字符串删掉

def not_empty(s):    return s and s.strip()list(filter(not_empty, ['A', '', 'B', None, 'C', '  ']))# 结果: ['A', 'B', 'C']

05-01-03 sorted

sorted()函数也是一个高阶函数

数字list排序

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

数字list按绝对值大小排序

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

字符串list排序

>>> sorted(['bob', 'about', 'Zoo', 'Credit'])['Credit', 'Zoo', 'about', 'bob']

字符串list忽略大小写排序

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

字符串list忽略大小写反向排序

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

05-02 返回函数

函数作为返回值

可变参数的求和:返回和

def calc_sum(*args):    ax = 0    for n in args:        ax = ax + n    return ax
>>> calc_sum(1, 3, 5, 7, 9)25

可变参数的求和:返回求和的函数

def lazy_sum(*args):    def sum():        ax = 0        for n in args:            ax = ax + n        return ax    return sum
>>> f = lazy_sum(1, 3, 5, 7, 9)>>> f<function lazy_sum.<locals>.sum at 0x101c6ed90>>>> f()25

05-03 匿名函数

计算f(x)=x^2

函数

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

匿名函数

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

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


lambda x: x * x

相当于

def f(x):    return x * x

特点

  • 只能有一个表达式,不用写return,返回值就是该表达式的结果
  • 函数没有名字,不必担心函数名冲突
  • 匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数
->>> f = lambda x: x * x>>> f<function <lambda> at 0x101c6ef28>>>> f(5)25
  • 匿名函数可以作为返回值返回
def build(x, y):    return lambda: x * x + y * y

05-04 装饰器(Decorator)

作用:增强函数的功能

示例:在函数调用前打印函数名

定义装饰器

def log(func):    def wrapper(*args, **kw):        print(func.__name__)        return func(*args, **kw)    return wrapper

定义函数

@logdef now():    print('2017-9-6')

调用函数

>>> now()now():2017-9-6

把@log放到now()函数的定义处,相当于执行了语句:

now = log(now)

05-05 偏函数(Partial function)

int()可以把字符串转换成整数

>>> int('12345')12345>>> int('12345', base=8)5349

定义一个int2()的函数,默认把base=2传进去

def int2(x, base=2):    return int(x, base)
>>> int2('1000000')64>>> int2('1010101')85

偏函数 创建 int2( )

>>> import functools>>> int2 = functools.partial(int, base=2)>>> int2('1000000')64>>> int2('1010101')85

作用:把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单

原创粉丝点击