【14】Python学习笔记:函数作用域,匿名函数,函数式编程,高阶函数,尾递归优化,map,filter,reduce函数

函数作用域

函数的作用域只跟函数声明时定义的作用域有关,跟函数的调用位置无任何关系。

name = 'alex'

def foo():
    name = 'lhf'

    def bar():
        name = 'wupeiqi'
        print(name)

        def tt():
            print(name)

        return tt

    return bar

r1 = foo()
print('--' * 20)
r2 = r1()  # tt
print('--' * 20)
r3 = r2()

得到输出jie'结果:

----------------------------------------
wupeiqi
----------------------------------------
wupeiqi

匿名函数lambda

格式:lambda 参数:返回值

name = 'alex'
func = lambda x: x + '_sb'
res = func(name)
print('匿名函数的运行结果', res)

函数式编程

函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。

而函数式编程(请注意多了一个“式”字)——Functional Programming,虽然也可以归结到面向过程的程序设计,但其思想更接近数学计算。

我们首先要搞明白计算机(Computer)和计算(Compute)的概念。

在计算机的层次上,CPU执行的是加减乘除的指令代码,以及各种条件判断和跳转指令,所以,汇编语言是最贴近计算机的语言。

而计算则指数学意义上的计算,越是抽象的计算,离计算机硬件越远。

对应到编程语言,就是越低级的语言,越贴近计算机,抽象程度低,执行效率高,比如C语言;越高级的语言,越贴近计算,抽象程度高,执行效率低,比如Lisp语言。

函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。

函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!

Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。

高阶函数

高阶函数:

1. 函数接收的参数是一个函数名。

def foo(n):
    print(n)

def bar(name):
    print('my name is %s' %name)

# foo(bar)
# foo(bar())
foo(bar('alex'))

2. 返回值中包含函数。

def bar():
    print('from bar')
def foo():
    print('from foo')
    return bar
n=foo()
n()
def hanle():
    print('from handle')
    return hanle
h=hanle()
h()

得到输出结果:

from foo
from bar
from handle
from handle

尾递归优化

如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。尾递归函数的特点是在回归过程中不用做任何操作,这个特性很重要,因为大多数现代的编译器会利用这种特点自动生成优化的代码。

编译器检测到一个函数调用是尾递归的时候,它就覆盖当前的活动记录而不是在栈中去创建一个新的。编译器可以做到这点,因为递归调用是当前活跃期内最后一条待执行的语句,于是当这个调用返回时栈帧中并没有其他事情可做,因此也就没有保存栈帧的必要了。通过覆盖当前的栈帧而不是在其之上重新添加一个,这样所使用的栈空间就大大缩减了,这使得实际的运行效率会变得更高。

例如,求阶乘的函数:

def fact(n):
    if n == 1:
        return n
    return n * fact(n - 1);

print(fact(5))

用尾递归优化优化后:

def fact(n):
    return fact_iter(n, 1);

def fact_iter(num, product):
    if num == 1:
        return product
    return fact_iter(num - 1, num * product)

print(fact(5))

尾调用由于是函数的最后一步操作,所以不需要保留外层函数的调用记录,因为调用位置、内部变量等信息都不会再用到了。所以尾递归优化可以有效的防止栈溢出,但是尾递归优化需要编译器或者解释器的支持,遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的fact(n)函数改成尾递归方式,如果所求数字的阶乘过大,也会导致栈溢出。

参考自:https://blog.csdn.net/u013181595/article/details/76336181

博主:dayL_W

map函数

先来看看用函数如何实现映射功能:

num_l = [1,2,10,5,3,7]

def map_test(func,array):
    ret=[]
    for i in array:
        res=func(i) # add_one(i)
        ret.append(res)
    return ret

print(map_test(lambda x:x+1,num_l))

使用map函数实现映射功能:

res=map(lambda x:x+1,num_l)
print('内置函数map,处理结果',res)
print('转换成列表',list(res))

map函数处理可迭代对象,因此也能处理字符串:

msg='linhaifeng'
print(list(map(lambda x:x.upper(),msg)))

filter函数

先来看看用函数如何实现过滤功能:

movie_people = ['alex_sb', 'wupeiqi_sb', 'linhaifeng', 'yuanhao_sb']

def filter_test(func, array):
    ret = []
    for p in array:
        if not func(p):
            ret.append(p)
    return ret

res = filter_test(lambda n: n.endswith('sb'), movie_people)
print(res)

使用filter函数实现过滤功能:

res = filter(lambda n: not n.endswith('sb'), movie_people)
print(list(res))

reduce函数

先来看看如何用函数实现降维功能:

num_l=[1,2,3,100]
def reduce_test(func,array,init=None):
    if init is None:
        res=array.pop(0)
    else:
        res=init
    for num in array:
        res=func(res,num)
    return res

print(reduce_test(lambda x,y:x*y,num_l,100))

使用reduce函数:

from functools import reduce
num_l=[1,2,3,100]
print(reduce(lambda x,y:x+y,num_l,1))

猜你喜欢

转载自blog.csdn.net/CALL_ME_K/article/details/81663649