python语法拾遗-高阶函数

允我心安 提交于 2020-01-22 07:36:01

title: python语法拾遗
date: 2019-11-12 12:23:49
categories:

  • Python
  • Python语法相关
    tags:
  • python
  • 语法使用
    description: python高阶函数(迭代器,装饰器,map-reduce等)

python高阶函数(迭代器,装饰器,map-reduce等)

高级特征

迭代

迭代通过for...in来完成,作用对象可以是list,tuple,dict,str之类的可迭代对象。如下迭代dict类型:

d = {'a': 1, 'b': 2, 'c': 3}
for key in d:
    print(key)  #a,b,c

注:dict字典数据类型,内部原始没有顺序,故输出顺序可能不同。dict默认迭代key值,如要迭代value值,需要使用for value in d.values();如要迭代键值对,要使用for k,v in d.items()

可迭代对象的判断方法,使用collections模块的Iterable类型判断:

from collections import Iterable
isinstance('abc',Iterable)  # 返回True,即str为可迭代对象

enumerate函数,可以将list变成索引-元素对:

for i,v in enumerate(['A', 'B', 'C']):
    print(i,v)#0 A;1 B;2 C

生成器(generator)

创建方法(一):
将列表生成式的’[]‘改写成’()'即可,如:

L = [x for x in range(5)] #这是个列表
L2 = (x for x in range(5)) #这是个生成器

创建方法(二):
在循环函数内使用yield关键字代替输出。

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'

调用next()函数可以逐个输出循环体内值,调用一次输出一次,直到输出完毕后,报StopIteration错误。在循环体中,每执行一次yield则跳出该循环。

生成器也是可迭代对象,所以可以使用for...in循环输出,且最后不会有StopIteration报错。

迭代器(Iterator)

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator,而可迭代对象叫:Iterable。所以,生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。

iter()函数将可迭代对象,转换为iterator。

高阶函数

map-reduce

map函数:map(function_to_apply,list_of_inputs),接收两个参数,一个函数,一个Iterable。该函数将序列的每个元素逐个作用到function上,并返回一个Iterator。

#e.g.
items = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, items)) # 1,4,9,16,25

除此之外,map函数还可以接收,由函数组成的Iterable

def multiply(x):
    return x*x
def add(x):
    return x+x
funcs = [multiply,add]
for i in range(5):
    print(list(map(lambda x: x(i),funcs)))
# Output:
# [0, 0]
# [1, 2]
# [4, 4]
# [9, 6]
# [16, 8]

reduce函数:形式与map相同,但是参数函数必须接收两个值,reduce把结果继续和序列的下一个元素做累积计算,类似:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

from functools import reduce
product = reduce((lambda x,y:x*y),[1,2,3,4])
# output:24

filter

filter函数:形式与map相同,但filter将元素代入func做判断,返回满足条件的元素(Iterator)。

odd_list = list(filter((lambda x: x%2==1),[1,2,4,5,6,7]))

闭包

在函数中返回函数,则“外部函数”的变量可以被“内部函数”引用,但是,返回函数不要引用任何循环变量,或者后续会发生变化的变量。函数名后没有加"()“的,只能起到传递函数的作用,加上”()"才能真正执行。如下例

def adder(x):
    def wrapper(y):
        return x + y
    return wrapper

adder5 = adder(5)
# 输出 15
adder5(10)
# 输出 11
adder5(6)

装饰器(decorator)

函数可以作为参数传给另⼀个函数。装饰器的作用就是将目标函数①作为参数,传递给另一个函数②。以达到在不改变目标函数①的前提下,添加函数②的功能,还可以接收函数②的新参数(可能需要多层嵌套)。类似如此:

@func1  #func1一般为针对func2的闭包函数。
def func2():
    print('some')
#定义完毕后,执行func2时,实际是执行func2 = func1(func2)。此时func2指向的是func1的内部函数。可通过func2.__name__查看。
#此时,在最后的"封装"步骤前添加:@functools.wraps(func)可以修正__name__

示例:

from functools import wraps
def decorator_name(f):
    @wraps(f)
    def decorated(*args,**kwargs):
        if not can_run:
            return 'func will not run'
        return f(*args,**kwargs)
    return decorated
@decorator_name
def func():
    return('func is running')

can_run=True
print(func())
# output: Function is running

can_run =False
print(func())
# Output: Function will not run

func():
    return('func is running')

can_run=True
print(func())
# output: Function is running

can_run =False
print(func())
# Output: Function will not run
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!