1、嵌套函数
之前演示的都是全局函数,并将它们定义在全局作用域中。
函数还可以定义在另外的函数体中,称作“嵌套函数”。
代码演示:
def calculate(n1, n2, opr):
# 定义相加函数
def add(a, b):
return a + b
# 定义相减函数
def sub(a, b):
return a - b
if opr == '+':
return add(n1, n2)
else:
return sub(n1, n2)
print(calculate(20, 20, '+'))
# print(add(20, 20))
结果:
注意:外部函数内的嵌套函数,在外部函数体之外不可直接访问;
嵌套函数可以访问所在外部函数中的变量,而外部函数不可访问嵌套函数局部变量。
2、函数式编程基础
函数式编程与面向对象编程一样都是一种编程范式,函数式编程也称为面向函数的编程。
Python并不是彻底的函数式编程语言,但还是提供了一些函数式编程的必备技术,主要有函数类型和lambda表达式,他们是实现函数式编程的基础。
- 函数类型
Python提供了一种函数类型function,任何函数都有函数类型,函数调用时,就创建了函数类型实例,即函数对象。
代码演示:(对上例代码重构)
def calculate(opr):
# 定义相加函数
def add(a, b):
return a + b
# 定义相减函数
def sub(a, b):
return a - b
if opr == '+':
return add
else:
return sub
a = calculate('+')
b = calculate('-')
print(type(a))
print(type(b))
print('10 + 10 = {0}'.format(a(10, 10)))
print('10 - 10 = {0}'.format(b(10, 10)))
结果:
注意:从结果可以看出,函数calculate的返回值是函数类型的;
在语句a(10, 10),b(10, 10)中才真真的调用了add()和sub()函数
- lambda表达式
lambda表达式本质上是一种匿名函数,匿名函数也是函数,有函数类型,也可以创建函数对象。
定义lambda表达式语法如下:
lambda 参数列表:lambda 体
lambda是关键字声明,这是一个lambda表达式,“参数列表”与函数参数列表是一样的,但不需要用小括号括起来,冒号后边是“lambda体”,lambda表达式的主要代码在此处编写,类似函数体。
注意:lambda体部分不能是一个代码块,不能包含多条语句,只能有一条语句,语句会计算一个结果返回给lambda表达式;
与函数不同的是,不需要return语句返回。
与其他语言中的lambda表达式相比,Python的lambda表达式只能处理一些简单的计算。
代码演示(上例代码重构):
def calculate(opr):
if opr == '+':
return lambda a, b: (a + b)
else:
return lambda a, b: (a - b)
c = calculate('+')
d = calculate('-')
print(type(c))
print(type(d))
print('10 + 10 = {0}'.format(c(10, 10)))
print('10 - 10 = {0}'.format(d(10, 10)))
结果:
从结果可以看出,代码比之前的更简洁了,并且效果相同。
- 三大基础函数
函数式编程的本质是通过函数处理数据,过滤、映射和聚合是处理数据的三大基本操作。针对这三种操作,Python提供了三个基础函数:filter()、map()、reduce()。
filter()函数 可以对迭代对象的元素进行过滤。 语法如下:
filter(function, iterable)
参数function是一个函数,参数iterable是可迭代对象。
filter()函数调用时iterable会被遍历,其中的元素被逐一传入function函数,function返回布尔值。在function函数中编写过滤条件,如果为True的元素会被保留,如果我False的元素则会被过滤。
代码演示:
a = range(1, 18)
b = filter(lambda it: it % 3 == 1, a)
print(list(b))
结果:
注意:代码中可以看出最后对b使用了list()函数,因为filter()函数返回的是一个地址,不变直观展示。
map()函数 可以对迭代对象的元素进行变换 语法如下:
map(function, iterable)
参数function是一个函数,参数iterable是可迭代对象。
map()函数调用时iterable会被遍历,其中的元素被逐一传入function函数,在function函数中对元素进行调换。
代码演示:
a = ['Tony', 'Tom', 'Ben', 'Alex']
b = map(lambda it: it.lower(), a)
c = map(lambda it: it.lower(), filter(lambda it: it.startswith('T'), a))
d = filter(lambda it: it.startswith('T'), a)
e = map(lambda it: it.lower(), d)
print(list(b))
print(list(c))
print(list(e))
结果:
注意:代码中可以看出最后对b,c,e使用了list()函数,因为map()函数返回的是一个地址,不变直观展示;并且可以看出filter()函数得到的是可迭代对象。
reduce()函数 可以对多个数据按照指定的算法积累叠加起来,最后输出一个数据 语法如下:
reduce(function, iterable[, initializer])
参数function是聚合操作函数,该函数有两个参数,参数iterable是可迭代对象,参数initializer初始值。
代码演示(对一个数列求和):
from functools import reduce
a = [10, 20, 30, 88, 66, 77, 8, 15]
b = reduce(lambda y, x: y + x, a)
c = reduce(lambda y, x: y + x, a, 1000)
print(b)
print(c)
结果:
注意:b,c不同之处在于c加入了初始值;lambda表达式表示的是对a迭代对象的元素求和。