前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >匿名函数,内置函数,闭包

匿名函数,内置函数,闭包

作者头像
py3study
发布2020-01-16 15:35:26
5470
发布2020-01-16 15:35:26
举报
文章被收录于专栏:python3python3
  1. 内容
    1. 匿名函数:一句话函数,比较简单的函数。 函数名 = lambda 参数 : 返回值
    1. 此函数不是没有名字,他是有名字的,他的名字就是你给其设置的变量,比如func。 func() 函数执行
    2. lambda 是定义匿名函数的关键字,相当于函数的def.
    3. lambda 后面直接加形参,形参加多少都可以,只要用逗号隔开就行。 #所有类型的形参都可以加,但是一般使用匿名函数只是加位置参数,其他的用不到 func = lambda a,b,*args,sex= 'alex',c,**kwargs: kwargs print(func(3, 4,c=666,name='alex')) # {'name': 'alex'}
    4. 返回值在冒号之后设置,返回值和正常的函数一样,可以是任意数据类型。
    5. 匿名函数不管多复杂.只能写一行.且逻辑结束后直接返回数据.

    练习: def func(a,b): return a + b print(func(4,5)) # 构建匿名函数 func1 = lambda a,b: a + b print(func1(1,2))

    • 接收一个可切片的数据,返回索引为0与2的对应的元素(元组形式)。
    • func2 = lambda a: (a[0],a[2]) print(func2([22,33,44,55])) #(22,44) print(func2('asdfg')) #('a', 'd')
    • 写匿名函数:接收两个int参数,将较大的数据返回。
    • func = lambda a,b: a if a > b else b print(func(5,7)) # 7
    1. 内置函数 # # python 提供了68个内置函数。 reversed() 内建函数将返回一个反序访问的迭代器。 enumerate() 内建函数同样也返回迭代器。 和range类似,map 、zip以及filter内置函数在Python 3.0 中也转变成迭代器以节约内存空间。 #print() ''' 源码分析 def print(self, *args, sep=' ', end='\n', file=None): # known special case of print """ print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False) file: 默认是输出到屏幕,如果设置为文件句柄,输出到文件 sep: 打印多个值之间的分隔符,默认为空格 end: 每一次打印的结尾,默认为换行符 flush: 立即把内容输出到流文件,不作缓存 """ ''' print(1,2,3,4)#1 2 3 4 print(1,2,3,4,sep='&')#1&2&3&4 print(1,2,3,sep='*')#1*2*3 print(111,end='') print(222)#两行的结果:111222 f = open('log','w',encoding='utf-8') print('写入文件',file=f,flush=True) #int() #str() #bytes() 把字符串转换成bytes类型 # 将字符串转换成字节 s = '你好' bs = bytes(s,encoding='utf-8') print(bs) #b'\xe4\xbd\xa0\xe5\xa5\xbd' # 将字节转换成字符串 bs = b'\xe4\xbd\xa0\xe5\xa5\xbd' s1 = str(bs,encoding='utf-8') print(s1) #你好 #bool() #set() # list() 将一个可迭代对象转换成列表 l1 = list() #空列表 l2 = list('abcd') print(l2)#['a', 'b', 'c', 'd'] #tuple() 将一个可迭代对象转换成元组 tu1 = tuple('abcd') print(tu1)#('a', 'b', 'c', 'd') # dict 创建字典的几种方式 # 直接创建 dic = {'name': '太白', 'age': 18} # 元组的解构 dic = dict([(1,'one'),(2,'two'),(3,'three')] # dic = dict(one=1,two=2,three=3) print(dic)#{'one': 1, 'two': 2, 'three': 3} # fromkeys dic = { k: v for k,v in [('one', 1),('two', 2),('three', 3)]} print(dic)#{'one': 1, 'two': 2, 'three': 3} # update dic = {} dic.update([(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]) print(dic)#{1: 'a', 2: 'b', 3: 'c', 4: 'd'} # 字典的推导式 dic = { k: v for k,v in [('one', 1),('two', 2),('three', 3)]} print(dic)#{'one': 1, 'two': 2, 'three': 3} lst1 = ['jay', 'jj', 'meet'] lst2 = ['周杰伦','林俊杰','元宝'] dic = { lst2[i]: lst1[i] for i in range(len(lst1))} print(dic)#{'周杰伦': 'jay', '林俊杰': 'jj', '元宝': 'meet'} # dic = dict(zip(['one', 'two', 'three'],[1, 2, 3])) print(dic)#{'one': 1, 'two': 2, 'three': 3} # abs() 返回绝对值*** i = -5 print(abs(i))#5 print(abs(-6)) # sum()求和【针对数字】,可以设置初始 *** print(sum([1.1,2.4,3.88]))#7.38 print(sum([1,2,3]))#6 print(sum((1,2,3),100))#106 可以设置初始值,让初始值为100 l1 = [i for i in range(10)] print(sum(l1))#45 print(sum(l1,100))#145 s1 = '12345' #字符串 print(sum(s1)) # 错误 # reversed 返回的是一个翻转的迭代器(将一个序列翻转, 返回翻转序列的迭代器) *** l1 = [i for i in range(10)] l1.reverse() # 列表的方法 print(l1)#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]#对原列表操作 ret = reversed([1, 4, 3, 7, 9]) print(list(ret)) # [9, 7, 3, 4, 1] l1 = [i for i in range(10)] obj = reversed(l1) #将可迭代对象转化为迭代器 返回的是迭代器 print(obj)#<list_reverseiterator object at 0x000002092EC877F0> print(l1)#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] #原列表不变 print(list(obj))#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]转化为列表进行取值 # zip 拉链方法 ***面试题会考 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的内容,如果各个迭代器的元素个数不一致,则按照长度最短的返回。 l1 = [1, 2, 3, 4, 5] tu1 = ('太白', 'b哥', '德刚') s1 = 'abcd' obj = zip(l1,tu1,s1) print(obj)#<zip object at 0x00000284D0211088> python内部提供的迭代器 for i in obj: print(i) #结果: (1, '太白', 'a') (2, 'b哥', 'b') (3, '德刚', 'c') 或: print(list(obj))#[(1, '太白', 'a'), (2, 'b哥', 'b'), (3, '德刚', 'c')] # ************* 以下方法最最最重要 # min()求最小值 和 max()求最大值 # 返回此序列最小值 l1 = [33, 2, 3, 54, 7, -1, -9] print(min(l1))#-9 print(min([1,2,-5]))#-5 # 以绝对值的方式获取最小值 #1:求最小的绝对值 l1 = [33, 2, 3, 54, 7, -1, -9] l2 = [] func = lambda a: abs(a) for i in l1: l2.append(func(i)) print(l2)#[33, 2, 3, 54, 7, 1, 9] print(min(l2)) #1 #2:找出绝对值最小的元素 #自己写函数 l1 = [33, 2, 3, 54, 7, -1, -9] def abss(a): return abs(a) print(min(l1,key=abss)) #-1 #直接用内置函数abs() l1 = [33, 2, 3, 54, 7, -1, -9] print(min(l1,key=abs))#-1 print(min([1,2,-5,],key=abs)) #1 ## key=函数名,按照绝对值的大小,返回此序列最小值 print(min(-5,6,-3,key=lambda x:abs(x)))# -3 可以设置很多参数比较大小 【凡是可以加key的:它会自动的将可迭代对象中的每个元素按照顺序传入key对应的函数中,以返回值比较大小。】 【 min函数循环的是什么,返回的就是什么。正常情况下:列表:返回列表中的元素。字典:返回字典的键。】 【 加key,是可以加'函数名',min自动会获取传入min函数中的参数的每个元素,然后通过函数的返回值比较大小((key=函数名,看该函数返回的是什么。按照什么比较大小,就将什么设置为返回值),返回最小的返回值对应的那个传入参数的元素。】 dic = {'a': 3, 'b': 2, 'c': 1} # 求出值最小的键 print(min(dic)) #a min默认会按照字典的键去比较大小。 #按照字典的值比较大小 #1: dic = {'a':3,'b':2,'c':1} def func(a): return dic[a] #key对应的函数的返回值是什么,就按什么比较大小 print(min(dic,key=func))#c #2:min函数按照什么循环,lambda函数的参数位置就写什么。后面的返回值是根据它转化的。 dic = {'a':3,'b':2,'c':1} func = lambda a :dic[a] print(min(dic,key=func))#c #简化: # a为dic的key,按lambda的返回值(即dic的值dic[a])进行比较,返回最小的值对应的键。 dic = {'a':3,'b':2,'c':1} print(min(dic,key=lambda a:dic[a])) # c 字典中最小值对应的键。min函数循环的是什么,返回的就是什么。按键循环 print(dic[min(dic,key=lambda a:dic[a])]) #1 字典中最小的值 l2 = [('太白', 18), ('alex', 73), ('wusir', 35), ('口天吴', 41)] print(min(l2)) #('alex', 73) #min函数返回元组,它循环的是什么,返回的就是什么。默认按照列表中每个元组中第一个元素的首字母的Unicode比较 #自定制,+key print(min(l2,key=lambda x:x[1]))#('太白', 18) print(min(l2,key=lambda x:x[1])[0])#太白 print(min(l2,key=lambda x:x[1])[1])#18 # max最大值 与最小值用法相同 # sorted 排序函数(可加key自定制) 语法:sorted(iterable,key=None,reverse=False) iterable : 可迭代对象 key: 排序规则(排序函数),在sorted内部会将可迭代对象中的每一个元素传递给这个函数的参数.根据函数运算的结果进行排序 reverse :是否是倒叙,True 倒叙 False 正序 l1 = [22, 33, 1, 2, 8, 7, 6, 5] l2 = sorted(l1) print(l1)#[22, 33, 1, 2, 8, 7, 6, 5]原列表不会改变 print(l2)#[1, 2, 5, 6, 7, 8, 22, 33] #倒序: lst = [1,3,2,5,4] lst3 = sorted(lst,reverse=True) print(lst3) #[5, 4, 3, 2, 1] #字典使用sorted排序 dic = {1:'a',3:'c',2:'b'} print(sorted(dic)) # 字典排序返回的就是排序后的key [1, 2, 3] l2 = [('大壮', 76), ('雪飞', 70), ('纳钦', 94), ('张珵', 98), ('b哥',96)] print(sorted(l2))#[('b哥', 96), ('大壮', 76), ('张珵', 98), ('纳钦', 94), ('雪飞', 70)] print(sorted(l2,key= lambda x:x[1])) # [('雪飞', 70), ('大壮', 76), ('纳钦', 94), ('b哥', 96), ('张珵', 98)]返回的是一个列表,默认从低到高 print(sorted(l2,key= lambda x:x[1],reverse=True)) #[('张珵', 98), ('b哥', 96), ('纳钦', 94), ('大壮', 76), ('雪飞', 70)] #和函数组合使用 #定义一个列表,然后根据元素的长度排序 lst = ['天龙八部', '西游记', '红楼梦', '三国演义'] #计算字符串的长度 def func(s): return len(s) print(sorted(lst, key=func))#['西游记', '红楼梦', '天龙八部', '三国演义'] #和lambda组合使用 lst = ['天龙八部', '西游记', '红楼梦', '三国演义'] print(sorted(lst, key=lambda s: len(s)))#['西游记', '红楼梦', '天龙八部', '三国演义'] #按照年龄对学生信息进行排序 lst = [{'id': 1, 'name': 'alex', 'age': 18}, {'id': 2, 'name': 'wusir', 'age': 17}, {'id': 3, 'name': 'taibai', 'age': 16}, ] print(sorted(lst, key=lambda e: e['age']))#[{'id': 3, 'name': 'taibai', 'age': 16}, {'id': 2, 'name': 'wusir', 'age': 17}, {'id': 1, 'name': 'alex', 'age': 18}] # filter()筛选过滤 类似于列表推导式的筛选模式 返回的是迭代器 语法: filter(function, iterable) function: 用来筛选的函数, 在filter中会自动的把iterable中的元素传递给function, 然后根据function返回的True或者False来判断是否保留此项数据 iterable: 可迭代对象 lst = [{'id': 1, 'name': 'alex', 'age': 18}, {'id': 1, 'name': 'wusir', 'age': 17}, {'id': 1, 'name': 'taibai', 'age': 16}, ] ls = filter(lambda e: e['age'] > 16, lst) #返回的是迭代器 print(list(ls))#转化成列表 [{'id': 1, 'name': 'alex', 'age': 18}, {'id': 1, 'name': 'wusir', 'age': 17}] #列表推导式的筛选模式 l1 = [2, 3, 4, 1, 6, 7, 8] print([i for i in l1 if i > 3]) # 返回的是列表 l1 = [2, 3, 4, 1, 6, 7, 8] ret = filter(lambda x: x > 3,l1) # 返回的是迭代器 print(ret)#<filter object at 0x00000165B06D7F28> print(list(ret))#[4, 6, 7, 8] # map() 映射函数 类似于列表推导式的循环模式 返回的是迭代器 语法: map(function,iterable) 可以对可迭代对象中的每一个元素进映射,分别取出来执行function #列表推导式的循环模式 print([i**2 for i in range(1,6)]) # 返回的是列表 #[1, 4, 9, 16, 25] #计算每个元素的平方,返回新列表 ret = map(lambda x: x**2,range(1,6)) # 返回的是迭代器 print(ret)#<map object at 0x00000191237C7EB8> print(list(ret))#[1, 4, 9, 16, 25] # 计算两个列表中相同位置的数据的和 lst1 = [1, 2, 3, 4, 5] lst2 = [2, 4, 6, 8, 10] print(list(map(lambda x, y: x+y, lst1, lst2)))#[3, 6, 9, 12, 15] # reduce # 在Python2.x版本中recude是直接 import就可以的, Python3.x版本中需要从functools这个包中导入 # reduce 的使用方式:reduce(函数名,可迭代对象) # 这两个参数必须都要有,缺一个不行 from functools import reduce def func(x,y): return x + y ret = reduce(func,[3,4,5,6,7]) print(ret) # 结果 25 #普通函数版 from functools import reduce def func(x,y): return x * 10 + y l = reduce(func,[1,2,3,4]) print(l)#1234 第一次的时候 x是1, y是2 x乘以10就是10,然后加上y也就是2最终结果是12然后临时存储起来了 第二次的时候x是临时存储的值12 x乘以10就是 120 然后加上y也就是3最终结果是123临时存储起来了 第三次的时候x是临时存储的值123 x乘以10就是 1230 然后加上y也就是4最终结果是1234然后返回了 #匿名函数版 from functools import reduce l = reduce(lambda x,y:x*10+y,[1,2,3,4]) print(l)#1234 from functools import reduce def func(x,y): return x + y l = reduce(func,[11,2,3,4]) #第一次的时候取2个数据,之后都取1个。 print(l) ''' 第一次:x y : 11 2 x + y = 记录: 13 第二次:x = 13 y = 3 x + y = 记录: 16 第三次 x = 16 y = 4 ....... '''
    2. 闭包: 整个历史中的某个商品的平均收盘价。什么叫平局收盘价呢?就是从这个商品一出现开始,每天记录当天价格,然后计算他的平均值:平均值要考虑直至目前为止所有的价格。 比如大众推出了一款新车:小白轿车。 第一天价格为:100000元,平均收盘价:100000元 第二天价格为:110000元,平均收盘价:(100000 + 110000)/2 元 第三天价格为:120000元,平均收盘价:(100000 + 110000 + 120000)/3 元

# 封闭的东西: 保证数据的安全。 # 方案一: l1 = [] # 全局变量 数据不安全 li = [] def make_averager(new_value): l1.append(new_value) total = sum(l1) averager = total/len(l1) return averager print(make_averager(100000)) print(make_averager(110000)) .....(多行代码) l1.append(666) print(make_averager(120000)) print(make_averager(90000)) # 方案二: 数据安全,l1不能是全局变量。 # 每次执行的时候,l1列表都会重新赋值成[] li = [] def make_averager(new_value): l1 = [] l1.append(new_value) total = sum(l1) averager = total/len(l1) return averager print(make_averager(100000)) print(make_averager(110000)) .....(多行代码) print(make_averager(120000)) print(make_averager(90000)) # 方案三: 闭包 #在函数中嵌套了一个函数。avg 这个变量接收的实际是averager函数名,也就是其对应的内存地址,我执行了三次avg 也就是执行了三次averager这个函数。 def make_averager(): l1 = [] def averager(new_value): l1.append(new_value) print(l1) total = sum(l1) return total/len(l1) return averager avg = make_averager() # 【重点理解】返回值averager给avg avg得到了内层函数的内存地址,所以外层函数执行完后,只要有内层函数的内存地址,下面的print语句依然可以执行内层函数 print(avg(100000)) print(avg(110000)) print(avg(120000)) print(avg(190000)) ## 函数名.__code__.co_freevars 查看函数的自由变量 print(avg.__code__.co_freevars)#('l1',) # 函数名.__code__.co_varnames 查看函数的局部变量 print(avg.__code__.co_varnames)#('new_value', 'total') #获取具体的自由变量对象,也就是cell对象。 print(avg.__closure__)#(<cell at 0x0000029744E374C8: list object at 0x0000029744ECE948>,) #cell_contents 自由变量具体的值 print(avg.__closure__[0].cell_contents)#[] def func(): return 666 print(func)#<function func at 0x00000219A46C9AE8> 函数名指向函数的内存地址 print(globals())#不包含 'ret': 666 ret = func() print(globals())#包含 'ret': 666 闭包: 多用于面试题: 什么是闭包? 闭包有什么作用。 闭包的定义: 1,闭包只能存在嵌套函数中。闭包是嵌套在函数中的函数 2,闭包必须是内层函数对外层函数非全局变量的引用(使用),就会形成闭包。【使用:可改变 引用:直接使用,如print()】 自由变量:被引用的非全局变量也称作自由变量,这个自由变量会与内层函数产生一个绑定关系,自由变量不会在内存中消失,而且全局还引用不到。 闭包的作用:保证数据的安全。保存局部信息不被销毁,保证数据的安全性。 闭包的应用:可以保存一些非全局变量但是不易被销毁、改变的数据。装饰器 # 如何判断一个嵌套函数是不是闭包 1,闭包只能存在嵌套函数中。 2,内层函数对外层函数非全局变量的引用(使用),就会形成闭包。 # 例1:是闭包 def wrapper(): a = 1 #a是自由变量 def inner(): print(a) return inner ret = wrapper() # 例2:也是闭包!【讲】 def wrapper(a,b): #传参相当于a=2,b=3,相当于在函数内重新定义变量,所以a,b都是外层函数的非全局变量,即a,b都是自由变量 def inner(): print(a) print(b) return inner a = 2 b = 3 ret = wrapper(a,b) print(ret.__code__.co_freevars) # ('a', 'b') #用几个就有几个自由变量 print(ret.__closure__)#(<cell at 0x000001F3155274C8: int object at 0x00000000513A6C30>, <cell at 0x000001F3155274F8: int object at 0x00000000513A6C50>) print(ret.__closure__[0].cell_contents)# 2 print(ret.__closure__[1].cell_contents)# 3 #例3: def wrapper(): count = 1 # 不可变数据类型 def inner(): nonlocal count #count是自由变量 count += 1 print(count) # 1 inner() print(count) # 2 return inner ret = wrapper() print(ret.__code__.co_freevars)#('count',) # 如何代码判断闭包? def make_averager(): l1 = [] #l1是自由变量 def averager(new_value): l1.append(new_value) print(l1) total = sum(l1) return total/len(l1) return averager avg = make_averager() # averager print(avg.__code__.co_freevars)

  1. 总结
    • 匿名函数。
    • 内置函数。*** 一定要记住,敲3遍以上。 ** 尽量记住,2遍。
    • 闭包:多用于面试题: 什么是闭包? 闭包有什么作用。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-06-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档