函数式编程

一、高阶函数
将函数作为参数使用的函数。
func(n, funcA)

1、map()
map(function, , iterable, …) literable一个或多个序列
原意就是映射,即把集合或者列表的元素,每一个元素都按照一定规则进行操作,生成一个新的列表或者集合
map函数是系统提供的具有映射功能的函数,返回值是一个迭代对象(iterators迭代器)
示例:利用map()计算一个序列的的平方根。

>>>def square(x) :            # 计算平方数
...     return x ** 2
... 
>>> map(square, [1,2,3,4,5])   # 计算列表各个元素的平方
[1, 4, 9, 16, 25]
>>> map(lambda x: x ** 2, [1, 2, 3, 4, 5])  # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
 
# 提供了两个列表,对相同位置的列表数据进行相加
>>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
[3, 7, 11, 15, 19]

2、reduce()

reduce(function,  iterable [,  initializer])

function – 函数,有两个参数
iterable – 可迭代对象
initializer – 可选,初始参数
reduce() 函数会对参数序列中元素进行累积。

函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。

  • 注意事项
    -函数必须有两个参数
    -reduce([1,2,3,4,5]) == f( f(f(f(1,2),3), 4),5)
    -reduce 需要导入functools包
>>>import functools
>>>def add(x, y) :            # 两数相加
...     return x + y
... 
>>> reduce(add, [1,2,3,4,5])   # 计算列表和:1+2+3+4+5
15
>>> reduce(lambda x, y: x+y, [1,2,3,4,5])  # 使用 lambda 匿名函数
15

3、filter()
filter(function, iterable)
function – 判断函数,返回值是布尔值。
iterable – 可迭代对象。

过滤函数: 对一组数据进行过滤,符合条件的数据会生成一个新的列表并返回,返回类型“filter”,可用set()将结果转为集合进行打印

  • 跟map相比较:

-相同:都对列表的每一个元素逐一进行操作
-不同:
map会生成一个跟原来数据想对应的新队列
filter不一定,只要符合条件的才会进入新的数据集合

def isEven(a):
    return a % 2 == 0
list = [3,4,56,3,2,3,4556,67,4,4,3,23455,43]
rst = filter(isEven, list)
print(set(rst))

利用filter(),可以完成很多有用的功能,例如,删除 None 或者空字符串:

def is_not_empty(s):
    return s and len(s.strip()) > 0
filter(is_not_empty, ['test', None, '', 'str', '  ', 'END'])
结果:['test', 'str', 'END']

4、sorted()
排序算法函数

a = [234,22312,123,45,43,2,3,66723,34]
al = sorted(a, reverse=True)  #对列表进行倒序排列
print(al)
a = [-43,23,45,6,-23,2,-4345]
# 按照绝对值进行排序
# abs是求绝对值的意思
# 即按照绝对值的倒序排列
al = sorted(a, key=abs, reverse=True)
print(al)
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower) #忽略大小写排序
['about', 'bob', 'Credit', 'Zoo']

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

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

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

>>> f = lazy_sum(1, 3, 5, 7, 9)
>>> f
<function lazy_sum.<locals>.sum at 0x101c6ed90>

调用函数f时,才真正计算求和的结果:

>>> f()
25
  • 闭包(closure)
    当一个函数在内部定义函数,并且内部的函数应用外部函数的参数或者局部变量,当内部函数被当做返回值的时候,相关参数和变量保存在返回的函数中,这种结构,叫闭包

返回的函数并没有立刻执行,而是直到调用了f()才执行。我们来看一个例子:

def count():
    fs = []
    for i in range(1, 4):
        def f():
             return i*i
        fs.append(f)
    return fs
f1, f2, f3 = count()
  • 返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
  • 出现的问题:
    造成上述状况的原因是,返回函数引用了变量i, i并非立即执行,而是等到三个函数都返回的时候才统一使用,此时i已经变成了3,最终调用的时候,都返回的是 3*3
    此问题描述成:返回闭包时,返回函数不能引用任何循环变量
    解决方案: 再创建一个函数,用该函数的参数绑定循环变量的当前值,无论该循环变量以后如何改变,已经绑定的函数参数值不再改变
def count():
    def f(j):
        def g():
            return j*j
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
    return fs

三、装饰器(Decrator)
在不改动函数代码的基础上无限制扩展函数功能的一种机制,本质上讲,装饰器是一个返回函数的高阶函数
装饰器的使用: 使用@语法, 即在每次要扩展到函数定义前使用@+函数名

# 任务:
# 对hello函数进行功能扩展,每次执行hello万打印当前时间
import time
# 高阶函数,以函数作为参数
def printTime(f):
    def wrapper(*args, **kwargs):
        print("Time: ", time.ctime())
        return f(*args, **kwargs)
    return wrapper

上面代码中,内部函数要写*args, **kwargs参数,代表原传入参数不变

  • 使用方法1
# 上面定义了装饰器,使用的时候需要用到@, 此符号是python的语法糖
@printTime
def hello():
    print("Hello world")
    
hello()
  • 使用方法2
# 上面对函数的装饰使用了系统定义的语法糖
# 下面开始手动执行下装饰器
# 先定义函数

def hello3():
    print("我是手动执行的")
    
hello3()

hello3 = printTime(hello3)
hello3()

f = printTime(hello3)
f()
# 作业:
# 解释下面的执行结果

四、偏函数

  • 参数固定的函数,相当于一个由特定参数的函数体
  • functools.partial的作用是,把一个函数某些函数固定,返回一个新函数
def int16(x, base=16):
    return int(x, base)

int16("12345")
import functools
#实现上面int16的功能
int16 = functools.partial(int, base=16)

int16("12345")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值