python高阶函数_python笔记-高阶函数

一个函数可以接收另一个函数作为参数,这种函数就称之为高阶函数。 简单示例:

def add(x, y, f):

return f(x) + f(y)

print(add(-6, 4, abs))

map/reduce

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

例如有一个函数:

f(x)=x2

要把这个函数作用在一个list[1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现如下:

def f(x):

return x * x

L = [1, 2, 3, 4, 5, 6, 7, 8, 9]

r = map(f, L)

print(list(r))

输出结果:[1, 4, 9, 16, 25, 36, 49, 64, 81]

使用map()函数把list的所有整数转换为字符串:

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

输出结果:['1', '2', '3', '4', '5', '6', '7', '8', '9']

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

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

用reduce()把序列[1, 3, 5, 7, 9]变换成整数13579:

from functools import reduce

def fn(x, y):

return x * 10 + y

L = [1, 3, 5, 7, 9]

print(reduce(fn, L))

结果:13579

filter

filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

例如删掉一个序列中的偶数,保留奇数:

def is_odd(n):

return n % 2 == 1

L = [1, 2, 4, 5, 6, 9, 10, 15]

print(list(filter(is_odd, L)))

输出结果:[1, 5, 9, 15]

删除一个列表里面的空字符串:

def not_empty(s):

return s and s.strip()

L = filter(not_empty, ['A', '', 'B', None, 'C', ' '])

print(list(L))

输出结果:['A', 'B', 'C']

filter()返回的是原来的元素,filter()的第一个函数只能起到一个判断的作用。

sorted

Python内置的sorted()函数就可以对list进行排序:

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

输出结果:[-21, -12, 5, 9, 36]

sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序:

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

输出结果:[5, 9, -12, -21, 36]

字符串排序:

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

输出结果:['Credit', 'Zoo', 'about', 'bob']

对字符串排序,是按照ASCII的大小比较的,由于'Z' < 'a',结果,大写字母Z会排在小写字母a的前面。

给sorted()传入key函数,即可实现忽略大小写的排序:

L = ['bob', 'about', 'Zoo', 'Credit']

print(sorted(L, key=str.lower))

输出结果:['about', 'bob', 'Credit', 'Zoo']

要进行反向排序,不必改动key函数,可以传入第三个参数reverse=True:

L = ['bob', 'about', 'Zoo', 'Credit']

print(sorted(L, key=str.lower, reverse=True))

输出结果:['Zoo', 'Credit', 'bob', 'about']

返回函数

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。返回函数可以把一些计算延迟执行。例如,如果定义一个普通的求和函数:

def out_sum(lst):

#定义函数 in_sum

def in_sum():

return sum(lst)

#返回函数 in_sum

return in_sum

下面代码并没有对函数进行执行计算出结果,而是返回函数:

L = [1, 2, 3, 4, 5]

print(out_sum(L))

输出结果:.in_sum at 0x00000179D74F0400>

对返回的函数进行调用时,才计算出结果:

L = [1, 2, 3, 4, 5]

f = out_sum(L)

#函数名后加(),才是调用该函数。

print(f())

#结果 15

上面的例子中,函数out_sum中又的定义了函数in_sum,内部函数in_sum引用外部函数的参数和局部变量,当外部函数out_sum返回in_sum时,参数和变量保存在返回函数中,这种程序结构成为:闭包(Closure)。

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

当调用out_sum时候,每次返回的都是一个新的函数:

L = [1, 2, 3, 4, 5]

f1 = out_sum(L)

f2 = out_sum(L)

if f1 == f2:

print('YES')

else:

print('NO')

#结果 NO

#函数f1() 和 f2() 结果互不影响。

一个函数可以返回一个计算结果,也可以返回一个函数。返回一个函数时,牢记该函数并未执行,返回函数中不要引用任何可能会变化的变量。

匿名函数

当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。

L = [1, 2, 3, 4, 5, 6, 7, 8, 9]

print(list(map(lambda x: x * x, L)))

输出结果:[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

print(f)

#结果 at 0x000001DFDAF91E18>

print(f(5))

结果 25

装饰器

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

装饰器本质上是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限验证等场景,装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

示例:

import datetime

import time

import functools

def log(func):

# 避免经过装饰之后的原本函数名变成了 wrapper ,需要在 wrapper 前加入:

@functools.wraps(func)

# 接收add传参

def wrapper(*args, **kw):

# 参数解构,返回值赋给ret

ret = func(*args, **kw)

# 打印当前时间

print('当前时间:', datetime.datetime.now(), '\r=======')

# 返回 add 函数执行结果,并加以装饰

return('函数名:{}()\r参数:{}\r结算结果:{}'.format(func.__name__, args, ret))

return wrapper

# @log 等于 add = log(add) 也就是 wrapper()

@log

def add(*args):

j = 0

for i in args:

j += i

return j

t = (1, 2, 3, 4, 5)

print(add(*t))

#验证打印原函数名是否被修改

print('原函数名为:', add.__name__)

定义一个带参数的装饰器:

# -*- coding: utf-8 -*-

import functools

import datetime

def hello():

return 'hello!'

# 打印时间

def out_time():

print('当前时间:', datetime.datetime.now(), '\r=======')

# 定义一个带参数的装饰器

def log(f1, f2, f3):

# 传入add作为参数

def decorator(func):

# 避免经过装饰之后的原本函数名变成了 wrapper ,需要在 wrapper 前加入:

@functools.wraps(func)

# 接收add的传参

def wrapper(*args):

f2()

ret = func(*args)

print('{} {}'.format(f1(), f3))

print('使用函数为:{}() 参数为:{}'.format(func.__name__, args))

return '计算结果为:{}'.format(ret)

# 返回函数wrapper

return wrapper

# 返回函数decorator

return decorator

# 执行带参装饰器,@log 等价于 add = log(hello, out_time, '奔跑')(add)

@log(hello, out_time, '奔跑')

#定义一个垒加函数,形参为可变参数

def add(*args):

j = 0

for i in args:

j += i

return j

L = [1, 2, 3, 4]

#传入实参,解构

print(add(*L))

#验证原函数名是否被修改

print(add.__name__)

偏函数

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

用functools.partial创建一个偏函数:

import functools

int2 = functools.partial(int, base=2)

print(int2('1010'))

#相当于:

print(int('1010', base=2))

简单总结functools.partial的作用就是,把一个函数的某些参数给固定住(默认传入原函数),返回一个新的函数。

也可以在调用新函数时候传入其他参数:

print(int2('1010', base=10))

创建偏函数时,实际上可以接收函数对象、args和*kw这3个参数,当传入:

max2 = functools.partial(max, 10)

实际上会把10默认为*args的一部分自动加到左边,也就是:

max2(5, 6, 7)

相当于:

args = (10, 5, 6, 7)

max(*args)

结果为10。

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、效、安全和并发的编程语言,特别适用于构建性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、效、安全、并发的编程语言,特别适用于构建性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、效、安全和并发的编程语言,特别适用于构建性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、效、安全、并发的编程语言,特别适用于构建性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、效、安全和并发的编程语言,特别适用于构建性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、效、安全、并发的编程语言,特别适用于构建性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、效、安全和并发的编程语言,特别适用于构建性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、效、安全、并发的编程语言,特别适用于构建性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、效、安全和并发的编程语言,特别适用于构建性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、效、安全、并发的编程语言,特别适用于构建性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值