来源:《Python从小白到大牛》关东升
1、嵌套函数
前面定义的函数都是全局函数,并将他们定义在全局作用域中。函数还可定义在另外的函数体内,称作“嵌套函数”。
def calculate(n1,n2,opr):
multiple=2
# 定义相加函数
def add(a,b):
return(a+b)*multiple
# 定义相减函数
def sub(a,b):
return(a-b)*multiple
if opr=='+':
return add(n1,n2)
else:
return sub(n1,n2)
print(calculate(10,5,'+')) #输出结果是30
# add(10,5) 发生错误
# sub(10,5) 发生错误
上述代码中定义了两个嵌套函数add()和sub()。嵌套函数可以访问所在外部函数calculate()中的变量multiple,而外部函数不能访问嵌套函数局部变量。另外,嵌套函数的作用域在外部函数体内,因此在内部函数体之外直接访问嵌套函数会发生错误。
2、函数式编程基础
函数式编程(functional programming)与面向对象编程一样都是一种编程范式,函数式编程也称为面向函数的编程。
Python并不是彻底的函数式编程语言,但还是提供了一些函数式编程必备的技术,主要有函数类型和Lambda表达式,它们是实现函数式编程的基础。
2.1函数类型
Python提供了一种函数类型function,任何一个函数都有函数类型,函数调用时,就创建了函数类型实例,即函数对象。函数类型实例与其他类型实例一样,在使用场景上没有区别,它可以赋值给一个变量,也可以作为参数传递给一个函数,还可以作为函数返回值使用。
def calculate_fun(opr):
# 定义相加函数
def add(a,b):
return a+b
# 定义相减函数
def sub(a,b):
return a-b
if opr=='+':
return add
else:
return sub
f1=calculate_fun('+')
f2=calculate_fun('-')
print(type(f1)) # <class 'function'>
print("10+5={0}".format(f1(10,5))) 10+5=15
print("10-5={0}".format(f2(10,5))) 10-5=5
该函数返回的是函数对象
2.2 Lambda表达式
理解了函数类型和函数对象,学习Lambda表达式就简单了。Lambda表达式本质上是一种匿名函数,匿名函数也是函数,有函数类型,也可以创建函数对象。
定义 Lambda 表达式语法如下:
lambda 参数列表: Lambda体
lambda是关键字声明,这是一个Lambda表达式,“参数列表”与函数的参数列表是一样的,但不需要小括号括起来,冒号后面是“Lambda体”,Lambda表达式的主要代码在此处编写,类似于函数体。
注意:Lambda体部分不能是一个代码块,不能包含多条语句,只能有一条语句,语句会计算一个结果返回给Lambda表达式,但是与函数不同的是,不需要 使用return语句返回。与其它语言中的Lambda表达式相比,Python中提供的Lambda表达式只能处理一些简单的计算。
def calculate_fun(opr):
if opr=='+':
return lambda a,b:(a+b)
else:
return lambda a,b:(a-b)
f1 = calculate_fun('+')
f2 = calculate_fun('-')
print(type(f1)) # <class 'function'>
print("10+5={0}".format(f1(10,5))) # 10+5=15
print("10-5={0}".format(f2(10,5))) # 10-5=5
2.3 三大基础函数
函数式编程的本质是通过函数处理数据、过滤、映射和聚合是处理数据的三大基本操作。针对其中三大基本操作,Python提供了三个基础的函数:
filter()、map()和reduce()
2.3.1 filter()
过滤操作使用filter()函数,它可以对可迭代对象的元素进行过滤,filter()函数语法如下:
filter(function,iterable)
其中参数function是一个函数,参数iterable是可迭代对象。filter()函数调用时iterable会被遍历,它的元素被逐一传入function函数返回布尔值。在function函数中编写过滤条件,如果为True的元素被保留,如果为False的元素被过滤掉。
number_list=range(1,11)
number_filter=filter(lambda it : it % 2 =0,number_list)
print(list(number_filter)) # [2,4,6,8,10]
2.3.2 map()
映射操作使用map()函数,它可以对可迭代对象的元素进行变换,map()函数语法如下:
map(function,iterable)
其中参数function是一个函数,参数iterable是可迭代对象。map()函数调用时iterable会被遍历,它的元素被逐一传入function函数,在function函数中对元素进行变换。
user=['Tony','Tom','Ben','Alex']
user_map=map(lambda u : u.lower(),users) print(list(user_map)) # ['tony','tom','ben','alex']
上述map()函数将user列表元素转换为小写字母,变换使用Lambda表达式lambda u : u.lower()。map()函数返回的还不是一个列表,需要使用list()函数将变换之后的数据转换为列表。
函数式编程时数据可以从一个函数“流”入另外一个函数,但遗憾的是Python并不支持"链式"API.例如,想获取user列表中T开头的名字,再将其转换为小写字母,
这样的需求需要使用filter()函数进行过滤,再使用map()函数进行映射变换。
users=['Tony','Tom','Ben','Alex']
users_filter=filter(lambda u:u.startswith('T'),users)
# users_map=map(lambda u:u.lower(),users_filter)
users_map=map(lambda u:u.lower(),filter(lambda u:u.startswith('T'),users))
print(list(users_map))
2.3.3 reduce()
聚合操作会将多个数据聚合起来输出单个数据,聚合操作中最基础的是归纳函数reduce(),reduce()函数会将多个数据按照指定的算法积累叠加起来,最后输出一个数据。
reduce()函数语法如下:
reduce(function,iterable[,initializer])
参数function是聚合操作函数,该函数有两个参数,参数iterable是可迭代对象,参数initializer初始值。
from functools import reduce
a=(1,2,3,4)
a_reduce=reduce(lambda acc,i:acc+i,a) # 10
# a_reduce=reduce(lambda acc,i:acc+i,a,2) # 12
print(a_reduce)
reduce()函数是在functools模块中定义的,所以要使用reduce()函数需要导入functools模块。
调用的reduce()函数,其中lambda acc,i:acc+i是进行聚类操作的Lambda表达式,该Lambda表达式有两个参数,其中acc参数是上次累计计算结果,i是当前元素,acc+i表达式是进行累加。reduce()函数最后的计算结果是一个数值,可以直接通过reduce()函数返回。
1393



被折叠的 条评论
为什么被折叠?



