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
.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