【Python学习】函数式编程

函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数。

(一)高阶函数

把函数作为参数传入,这样的函数称为高阶函数。

  • 变量可指向函数
    函数本身可以赋值给变量,即:变量可指向函数
f = abs
print(f(-10))
  • 函数名也是变量
    函数名其实是指向函数的变量

-传入函数
函数的参数可以接收变量,一个函数可以接收另一个函数作为参数,这种函数称为高阶函数。

def sum(a,b,f):
	return f(a)+f(b)

1、map/reduce

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

  • map
# map
def f(x):
    return x * x

r = map(f,[1,2,3,4,5])
print(list(r))

map()传入的第一个参数是f,即函数对象本身。由于结果r是一个Iterator,Iterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list。map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单f(x)=x2,还可以计算任意复杂的函数。

x = [1,2,3,4,5,6,7]
print(list(map(str,x)))
  • reduce
    reduce把一个函数作用在一个序列[x1, x2, x3, …]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算。
# reduce
# 对序列求和
def add(x, y):
    return x + y


sum = reduce(add, [1, 2, 3, 4, 5])
print(sum)


# 把序列[1, 2, 3, 4, 5]变换成整数12345
def fn(x, y):
    return x * 10 + y


num = reduce(fn, [1, 2, 3, 4, 5])
print(num)

2、filter

过滤序列,和map()类似,filter()也接收一个函数和一个序列。filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。filter()函数返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list。

# filter
# list中。删掉偶数,保留奇数
def is_qi(x):
    return x % 2 == 1


l = list(filter(is_qi, [1, 2, 3, 4, 5, 6, 7, 8]))
print(l)

# 序列中空字符串删掉
def not_empty(s):
    return s and s.strip()
s = list(filter(not_empty,['a','','b',None,'c',' ']))
print(s)

3、sorted

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

# 排序算法
# sorted
l = sorted([3, 1, 2, 43, 12])
print(l)

# 按绝对值大小排序
abs = sorted([21, 2, 32, -23, -12], key=abs)
print(abs)

# 忽略大小写,按照字母序排序
st = sorted(['bob', 'Asd', 'Coo', 'dss'], key=str.lower)
print(st)

# 反向排序  reverse=True
s = sorted(['bob', 'Asd', 'Coo', 'dss', 'Ds'], key=str.lower, reverse=True)
print(s)

# 按名字排序
L = [('Bob', 75, 2), ('Adam', 92, 3), ('Bart', 66, 1), ('Lisa', 88, 4)]


# 按名字排序
def sorted_byName(t):
    t = t[0]
    return t


# 按成绩排序
def sorted_byScore(t):
    t = t[1]
    return t


# 按学号排序
def sorted_byNo(t):
    t = t[2]
    return t


L1 = sorted(L, key=sorted_byName)
print(L1)
L2 = sorted(L1, key=sorted_byScore)
print(L2)
L3 = sorted(L2, key=sorted_byNo)
print(L3)

(二)返回函数

把函数作为结果值返回。

# 可变参数求和
def c_sum(*args):
    a = 0
    for i in args:
        a = a + i
    return a


print(c_sum(1, 2, 3, 4))


# 返回求和函数
def return_sumFun(*args):
    def sum():
        a = 0
        for i in args:
            a = a + i
        return a

    return sum


f1 = return_sumFun(1, 2, 3, 4, 5)
f2 = return_sumFun(1, 2, 3, 4, 5)
print(f1 == f2)

print(f1)
print(f1())

闭包:当一个函数返回了一个函数后,其内部的局部变量还被新函数引用

# 利用闭包返回一个计数器函数,每次调用它返回递增整数
def createCounter():
    count = [0]
    def counter():
        count[0] += 1
        return count[0]
    return counter

countFun = createCounter()
print(countFun(),countFun(),countFun())

(三)匿名函数

在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。
【匿名函数】 : lambda x: x * x
关键字lambda表示匿名函数,冒号前面的x表示函数参数,只能有一个表达式,不用写return。匿名函数也是一个函数对象,可以把匿名函数赋值给一个变量,再利用变量来调用该函数。

# lambda
# 计算f(x)=x*x
def f(x):
    return x * x

n = f(2)
print(n)

# 匿名函数
n = lambda x: x * x
print(n(2))

# 匿名函数作为返回值
def bt(x, y):
    return lambda: x * x + y * y

f = bt(1, 3)
print(f())

l = list(filter(lambda n: n % 2 == 1, range(1, 20)))
print(l)

(四) 装饰器

在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator),decorator就是一个返回函数的高阶函数。

def log(func):
    def wrapper(*args, **kw):
        print('call %s():' %func.__name__)
        return func(*args, **kw)
    return wrapper

# @log放到now()函数的定义处,相当于执行了语句:now = log(now)
@log
def now():
    print('2020:2:24')

print(now())

(五) 偏函数

functools模块提供了很多有用的功能,其中一个就是偏函数(Partial function)。

  • int()函数可以把字符串转换为整数,当仅传入字符串时,int()函数默认按十进制转换。
# int
print(int('12345'))

# int()   base参数 默认值10 N进制转换
print(int('100', base=8))


# 转二进制字符串
def int2(x, base=2):
    return int(x, base)

print(int2('1000'))

  • functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2。
# 偏函数
import functools

int2 = functools.partial(int, base=2)
print(int2('1000'))

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值