您的位置:首页 > 编程语言 > Python开发

python笔记11 - lambda函数,globals()/locals()函数,eval()exec()函数,闭包函数,函数式编程,高阶函数

2017-10-31 10:32 701 查看
2017/10/16

.lambda函数,globals()/locals()函数,eval()exec()函数,闭包函数,函数式编程,高阶函数

1.lambda表达式(又称匿名函数对象)

作用:

    创建一个匿名(无名)函数对象

    同def类似,但是不提供函数名

语法:

    lambda [参数1,参数2,...]:表达式

    注:[]内的部分可以省略

--------------------------------------------------

实例:

def myadd(x,y):

    return x + y

可以改写为:

myadd = lambda x,y:x+y

myadd(10+20)

print('10+20=',myadd(10,20))

实例:@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

print('10+20=',(lambda x,y:x*y)(100,200))

--------------------------------------------------

实例:

def operator(fn,x,y):       

    return fn(x,y) 

operator((lambda a,b:a+b),100,200)

operator((lambda a,b:a*b),100,200)

del operator  #释放函数所占的内存空间,用完之后销毁

曾出现的bug分析总结:

在python的交互环境中执行以上程序,如果

def operator(fn,x,y):       

    return fn(x,y) 



operator((lambda a,b:a+b),100,200)

直接按没有空行,交出出现SyntaxError: invalid syntax bug错误交互环境下,如果写下函数语句(多个表达式,系统会认为你的函数表达式可能还没有写完,因此前面依旧有3个点 ... 

提示是否继续写语句,我们应该按回车表示已经结束函数的定义,在>>>提示符下进行键入operator((lambda a,b:a+b),100,200))

注意:operator((lambda a,b:a+b),100,200) 和 print('10+20=',(lambda x,y:x*y)(100,200)) 的写法

语法说明:

    lambda只是一个表达式,它用来创建一个函数对象;

    当labda表达式执行时(调用的时候),返回的是冒号(:)后面的表达式的值;

    lambda表达式创建的函数只能包含一条语句(一个表达式)

    lambda比函数简单且可以随时创建和销毁,有利于减少程序的偶合度(联想以前的电视连接线和现在的一根HDMI线)

实例练习:

写一个lambda表达式,求两个变量的最大值

def mymax(x,y):

    if x >= y:

        return x

    else:

        return y

mymax2 = lambda x,y:mymax(x,y)

print(mymax2(100,200))

新的解法(题意实际上是将一个定义函数改写成为lambda函数表达式):

(1)

def mymax(x,y):

    if x >= y:

        return x

    return y

(2)

def mymax(x,y):

    rturn max(x,y)

(3)正确解法

def mymax(x,y):

    rturn x if x >= y else y

改写:

mymax2 = lambda x,y : x if x >= y else y

print(mymax2(100,200))

----------------------------------------------------------------------------------------------------------------------------------------------

2.globals()/locals()函数

  globals() 返回当前全局作用域内变量的字典

  locals()  返回当前局部作用域内变量的字典

实例:

a = 1

b = 2

def fn(c,d):

    e = 300

    print('locals 返回:',locals())

    print('globals返回:',globals())

fn(100,200)

>>>

locals 返回: {'c': 100, 'e': 300, 'd': 200}

globals返回: {'a': 1, 'b': 2, 'fn': xxxxxxxxxxxx}@@@@@@@@@@@@@@@@@@@@@

globals返回: {'__name__': '__main__', '__spec__': None, 

'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f81a0d72a58>,

 'b': 2, '__doc__': None, 'a': 1, '__builtins__': <module 'builtins' (built-in)>, 

'__file__': 'yuan.py', 'fn': <function fn at 0x7f81a0e30f28>, '__package__': None, 

'__cached__': None}

实例:

a = 1

b = 2

def fn(c,d):

    e = 300

print('locals 返回:',locals())@@@@@@@@@@@@

    print('globals返回:',globals())

    d = globals()

    d['b'] = 10

fn(100,200)

print(d)  >>>10

----------------------------------------------------------------------------------------------------------------------------------------------

3.eval(),exec()函数

eval()函数作用:

    把一个字符串当成一个表达式来执行,返回表达式执行后的结果

eval()格式:

    eval(source,globals=None,local=None)@@@@@@@ @@@@@@@@@@@@@@@@

实例:

x = 100

y = 200

a = eval('x+y')

print(a)   

>>>300

总结('x+y')本应该是字符串表达式,但是eval将其作为一个表达式来执行并返回了

实例:

x = 100

y = 200

a = eval('x+y')

print(a)     #300

s = input('请输入字符串:')          #只能输入表达式例如1+2,如果输入字符串反而会出错---

a = eval(s)

print('请输入字符串的结果',a)   

>>>输入的数字字符串会像数字一样输出

实例:

x = 100

y = 200

a = eval('x+y')

print(a)

local_scope = {'x':5,'y':10}

a = eval('x+y',None,local_scope)

print('a=',a)

z = 300

a = eval('x*y+z',{'z':3333},local_scope)@@@@@@ @@@@@@@@@@@@

print(a)

----------------------------------------------------------------------------------------------------------------------------------------------

4.exec()函数:

作用:把一个字符串当做程序来执行

格式:

    exec(source,global=None,locals=None)

实例:

x = 100

y = 200

s = 'print('hello:',x,y)'

exec(s)   #hello:100 200

实例:

gs = {'x':10,'y':20}   #作用域

ls = {'x':1,'y':2}     #作用域

exec('z = x + y',gs,ls)              @@@@@@@@@@@@@@@@@@@

print(ls)   #{'x':1,'y':2,'z':3}

实例练习:

写一个程序的解释执行器,解释我们自己输入的程序

$./myprog.py

请输入程序:>>>> x = 100<回车>

请输入程序:>>>> x = 200<回车>

请输入程序:>>>> print('x+y',x+y)<回车>

x+y=300

提示:用exec()函数实现

a = input('请输入程序:')

b = input('请输入程序:')

c = input('请输入程序:')

exec(a)

exec(b)

新的解法:@@@@@@@@@@@@@@@@@@@@@@@

#!/usr/bin/python3 

while True:

    s = input('请输入程序:>>>')

    exec(s)                      #将任意写入的程序都用python3的解释执行器解释执行

----------------------------------------------------------------------------------------------------------------------------------------------

5.闭包 closure

    将组成函数的语句和这些语句的执行环境打包在一起时,得到的对象成为闭包

说明:

    如果一个内嵌函数访问函数外部作用域的变量,则这个函数就是闭包

实例:

def make_power(x):

    def fn(arg):

        return arg ** x  #本作用域内是没有x的绑定值的,因此去找其作用域外的变量值2

    return fn

f2 = make_power(2)       #f2绑定了一个函数,函数中绑定了一个值2

y = f2(100)             #平方 100的平方

f3 = make_power(3)       #f3绑定了一个函数,函数中绑定了一个值3

y = f3(4)               #立方 4的立方

注意:只有内嵌函数才能形成闭包,见以上的说明。

----------------------------------------------------------------------------------------------------------------------------------------------

6.函数式编程:

    指用一些列函数解决问题

函数式编程的好处:

    每一个函数完成细小的功能,一系列函数的任意组合可以完成大问题;

    函数仅接受输入并产生输出,不包含任何可能影响输出的内部状态

函数的可重入性:

    输入一定,则输出必须一定(函数没有用到函数外的变量)

可重入函数的优点:

    易于测试,易于调试,更高的生产率(软件、函数的复用),模块化(逻辑清晰),逻辑可证

实例-不可重入函数:

y = 200

def myadd(x):

    return x+y

print(myadd(10))    #210

y = 300

print(myadd(10))    #310

实例-可重入函数:

def add2(x+y):

    return x+y

----------------------------------------------------------------------------------------------------------------------------------------------

7.高阶函数:

    满足以下条件中的一个条件的函数即为高阶函数:

    1.函数接受一个或者多个函数作为参数输入

    2.函数返回一个函数

实例:

def operator(fn,x,y):       #函数作为参数

    return fn(x,y) 

python中内置(builtins)的高阶函数:map,filter,sorted

--------------------------------------------------

(1)map函数:

    map(func,*iterable)

    用函数和可迭代对象中的每个元素作为参数计算出新的可迭代对象,当最短的一个可迭代对象完成迭代后,迭代生成结束

实例:

#生成一个迭代器,此迭代器可以生成1-9的自然数的平方:1 4 9 16...

def power2(x):

    return x**2

mit = map(power2,range(1,10))  #range已经是一个可迭代器,map将range迭代器中的所有元素处理后再重新生成并返回一个迭代器,power2 没有括号,表示调用函数,而不是返回函数运行结果

>>> mit

<map object at 0x7f9068dd37f0>

>>> for x in mit:

...     print(x,end=' ')

... 

>>>1 4 9 16 25 36 49 64 81 

总结:

mit = map(power2,range(1,10)) 语句中全是函数或者是可迭代器,map函数,power2自定义函数,range(1,10)迭代函数(器,对象)

将后函数的迭代元素取出,供前函数使用,最后生成新迭代元素集,由map函数生成迭代器

实例:

#生成迭代器,1*4 ,2*3,3*2,4*1

def mymul(x,y):

    return x*y

mit = map(mymul,[1,2,3,4],[4,3,2,1])     #power2 没有括号,表示调用函数,而不是返回函数运行结果

for x in mit:

    print(x,end=' ')

>>>4 6 6 4

实例:

#求和:1**1 + 2**2 + 3**3 + ... + n**n ,用pow,sum,map,range函数组成来做

#知识点提示 pow(a,b,c)  表示 a**b%c

我的解法:

n = int(input('please enter a num:'))

mit = map(pow,range(1,n+1),range(1,n+1))

L = []

for x in mit:

    L.append(x)

print(sum(L))

新的解法1:

def mysum(n):

    def power(x):

        return pow(x,x)

    mit = map(power,range(1,1+n))

    return sum(mit)

a = int(input('please enter a num:'))

print(mysum(a))

新的解法2:

def mysum(n):

    return sum(map(pow,range(1,n+1),range(1,n+1)))

a = int(input('please enter a num:'))

print(mysum(a))

新的解法3:

def mysum(n):

    return sum(map(lambda x : pow(x,x),range(1,n+1)))

a = int(input('please enter a num:'))

print(mysum(a))

实例:

#求和: 1**9 + 2**8 + 3**7 + ... + 9**1 的和 11377

#提示:函数式编程 pow sum map range

def mysum(n):

    return sum(map(lambda x,y : (x ** y),range(1,n+1),range(n,0,-1)))

a = int(input('please enter a num:'))

print(mysum(a))

实例:@@@@@@@@@@@@@@@@@@@@@

mit = map(pow,[1,2,3,4],[3,2])

L = [x for x in mit]

print(L)

>>>[1,4]

总结:记得pow是幂运算!!!!!

--------------------------------------------------

(2)filter函数:

    filter(function or None,iterable)

    function是筛选条件

作用:

    筛选序列中的数据,返回一个可迭代对象,此可迭代对象将对iterable进行筛选

说明:

    function将对iterable中的每个元素进行求值,返回False则将此数据丢弃,返回True,则保留此数据

实例:

L = [x for x in range(10)]  #[0,1,2,3,4,5,6,7,8,9]

def isodd(x):                  #如果奇数则返回True

    return x % 2 == 1 

L2 = [x for x in filter(isodd,range(10))]    #filter函数中只有两个参数,一个是函数,另一个是迭代器函数

print(L2)

>>>[1, 3, 5, 7, 9]

--------------------------------------------------

(3)sorted函数

作用:

    将原可迭代对象的数据进行排序,生成排序后的列表

格式:

    sorted(iterable,key=None,reverse=False)

说明:

    key函数用来提供一个值,这个值将作为排序的依据

实例:

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

L2 = sorted(L)                      #[-4, -2, 0, 1, 3, 5]

L3 = sorted(L,reverse=True)         #[5,3,1,0,-2,-4]

L4 = sorted(L,key=abs)              #[0, 1, -2, 3, -4, 5]

L5 = sorted(L,key=abs,reverse=True) #[5, -4, 3, -2, 1, 0]

实例:

names = ['Tom','Jerry','Spike','Tyke']

L1 = sorted(names)                   #['Jerry', 'Spike', 'Tom', 'Tyke'] 首字母

L2 = sorted(names,key=len)           #['Tom', 'Tyke', 'Jerry', 'Spike']

pirnt(L1,L2)

实例:

'ekipS','ekyT''moT','yrreJ',  后再首字母  @@@@@@@@@@@@@@@@@@@@

names = ['Tom','Jerry','Spike','Tyke']

def k(x):

    return x[::-1]      #将字符串翻转,reversed.不能用

L = sorted(names,key=k) #翻转只是依据

print(L)                #['Spike', 'Tyke', 'Tom', 'Jerry']

实例-要求同上:

names = ['Tom','Jerry','Spike','Tyke']

L = sorted(names,key = lambda x : x[::-1])

print(L)

>>>['Spike', 'Tyke', 'Tom', 'Jerry']

=======================================================================================

8.递归函数(recursion):

    函数直接或间接是调用自身

实例:

def f():

    print('hello')

    f()

f()                       #调用函数

print('递归完成')

>>>

ello

hello

hello

hello

hello

...

最终bug提示:RecursionError: maximum recursion depth exceeded while calling a Python object

函数始终在调用自己,调用深度无限大,无限进入(屋子)(但是python系统中默认最多的递归深度是1000层),而不进行返回,

屏幕不会打印 递归完成

实例改进-方便观察:

import time

def f():

    print('hello')

    time.(1)

    f()

f()                       #调用函数

print('递归完成')

说明:

    递归一定要空值递归的层数,当符合某一条件时要终止递归调用;

    几乎所有的递归都能用while循环来代替

优缺点:

    优点:可以把问题简化,让思路清晰,代码更简洁

    缺点:递归因系统环境影响大,当递归深度太大,可能会得到不可预知的结果

实例:

#循环实现阶乘

def myfac(n):

    result = 1

    for x in range(1,n+1):

        result *= x

    return result

a = int(input('please enter a num:'))

print(myfac(a))

#递归实现阶乘  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

def myfac(n):

    if n == 1:                #递归 和 循环的思想类似,其循环的判断条件,既可以按顺序取数,例如 个数,升序, 也可以逆顺序排列,例如本题的降序

        return 1              #这里用很巧妙的方法将阶乘实现,其实际是从 n (n-1)... 一直乘到 1

    return n * myfac(n-1)

print('5!= ',myfac(5))

=======================================================================================

课后练习:

1.用filter函数将 1-100之间的所有素数prime放入到列表中并打印

L = [x for x in range(10)]  #[0,1,2,3,4,5,6,7,8,9]

def isodd(x):                  #如果奇数则返回True

    return x % 2 == 1 

L2 = [x for x in filter(isodd,range(10))]    #filter函数中只有两个参数,一个是函数,另一个是迭代器函数

2.用递归方式计算 1+2+3+  ...  +n的和

def mysum(n):

    ...#此处自己实现

3.用函数式编程,算出1-20的阶乘的和

4.改写之前学生信息的程序,每个人的信息有:

  姓名:name

  年龄:age

  成绩:score

输入5个学生的信息,然后做如下的操作:

按成绩从高到低打印学生信息;

按年龄从高到低打印学生信息;

按年龄从低到高打印学生信息;

按原来输入顺序打印学生信息(保持原来的列表不变);

1.

def isprime(n):

    for i in range(2,n):

        return n % i != 0 

L = [ x for x in filter(isprime,range(1,101))]

print(L)

2.

def fun(n):

    if n == 1:                

        return 1              

    return n + fun(n-1)

a = int(input('please enter a num:'))

print(fun(a))

3.

def fun(n):

    if n == 1:                

        return 1              

    return n * fun(n-1)      #算阶乘

L = []

for i in range(1,21):

    L.append(fun(i))

print(sum(L))

4.

第1次做题:

docs = []

for x in range(5):

    name = input("请输入第"+str(x+1)+"个学生的姓名:")

    age  = int(input("请输入第"+str(x+1)+"个学生的年龄:"))

    d = {"name":name,"age":age}

    docs.append(d)

print(docs)

L=docs.copy()    #浅拷贝  L=docs[::]也可以

print('+'+'-'*13+'+'+'-'*13+'+')

print('|'+'姓名'.center(12)+'|'+'age'.center(12)+'|')

print('+'+'-'*13+'+'+'-'*13+'+') 

for d in L:

    print("|",d["name"].center(13),"|",str(d["age"]).center(13),'|',sep='')

print('+'+'-'*13+'+'+'-'*13+'+') 

############

names = ['Tom','Jerry','Spike','Tyke']

L1 = sorted(names)                   #['Jerry', 'Spike', 'Tom', 'Tyke'] 首字母

L2 = sorted(names,key=len)           #['Tom', 'Tyke', 'Jerry', 'Spike']

pirnt(L1,L2)

############

def fun():

    for i in L:

    d['age']

for i in range(5):

def quzhi():

    for i in range(5):

        return L[i]['age']

L3 = sorted(L,key =quzhi )

s = [(q,1,3)(w,2,4)(e,4,5)]

L = sorted(s,lanbda s : s[2])

print(L)

第2次做题:

网络参考提示:

L = [{'name':'a','score':10},{'name':'b','score':30},{'name':'c','score':20}]

print(L)

L2 = sorted(L,key=lambda stu:stu['score'])

print(L2)

#----------------------------------------------------------------------正解如下————————————————

docs = []

for x in range(3):

    name = input("请输入第"+str(x+1)+"个学生的姓名:")

    age  = int(input("请输入第"+str(x+1)+"个学生的年龄:"))

    score = int(input("请输入第"+str(x+1)+"个学生的分数:"))

    d = {"name":name,"age":age,"score":score}

    docs.append(d)

L=docs.copy()    #浅拷贝  L=docs[::]也可以

#----------------------------------------------------------------------

print('+'+'-'*13+'+'+'-'*13+'+'+'-'*13+'+')

print('|'+'NAME'.center(13)+'|'+'AGE'.center(13)+'|'+'SCORE'.center(13)+'|')

print('+'+'-'*13+'+'+'-'*13+'+'+'-'*13+'+') 

for d in L:

    print("|",d["name"].center(13),"|",str(d["age"]).center(13),'|',str(d["score"]).center(13),'|',sep='')

print('+'+'-'*13+'+'+'-'*13+'+'+'-'*13+'+') 

#----------------------------------------------------------------------

L = sorted(L,key=lambda stu:stu['score'])

print('+'+'-'*13+'+'+'-'*13+'+'+'-'*13+'+')

print('|'+'NAME'.center(13)+'|'+'AGE'.center(13)+'|'+'SCORE'.center(13)+'|')

print('+'+'-'*13+'+'+'-'*13+'+'+'-'*13+'+') 

for d in L:

    print("|",d["name"].center(13),"|",str(d["age"]).center(13),'|',str(d["score"]).center(13),'|',sep='')

print('+'+'-'*13+'+'+'-'*13+'+'+'-'*13+'+') 

#----------------------------------------------------------------------

L = sorted(L,key=lambda stu:stu['age']) 

print('+'+'-'*13+'+'+'-'*13+'+'+'-'*13+'+')

print('|'+'NAME'.center(13)+'|'+'AGE'.center(13)+'|'+'SCORE'.center(13)+'|')

print('+'+'-'*13+'+'+'-'*13+'+'+'-'*13+'+') 

for d in L:

    print("|",d["name"].center(13),"|",str(d["age"]).center(13),'|',str(d["score"]).center(13),'|',sep='')

print('+'+'-'*13+'+'+'-'*13+'+'+'-'*13+'+') 

#----------------------------------------------------------------------

L = sorted(L,key=lambda stu:stu['age'],reverse = True) 

print('+'+'-'*13+'+'+'-'*13+'+'+'-'*13+'+')

print('|'+'NAME'.center(13)+'|'+'AGE'.center(13)+'|'+'SCORE'.center(13)+'|')

print('+'+'-'*13+'+'+'-'*13+'+'+'-'*13+'+') 

for d in L:

    print("|",d["name"].center(13),"|",str(d["age"]).center(13),'|',str(d["score"]).center(13),'|',sep='')

print('+'+'-'*13+'+'+'-'*13+'+'+'-'*13+'+')

可以使用输入重定向完成这道题,工作中是写好了脚本方便测试

Python3 shiyan.py < nn.txt

如果用./students.py运行,需要为该文件添加执行权限 chmod u+x shiyan.py 并在该程序文档的首行(必须是第一行)键入#!/usr/bin/python3  来声明python3 解释执行器的位置

如果是shell文件 则要键入   #!/usr/bin/bash
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: