lambda 函数所引起的闭包问题
来源:互联网 发布:端口映射软件使用教程 编辑:程序博客网 时间:2024/05/16 15:12
之前在某本书上看到一道题,要求是:用字符串sign中的每一个字符去分割s字符串,并得到最后的结果
s = 'ab;cd|efg|hi,jkl|mn\opq;rst,uvw/xyz'sign = ';|\/,'
书中给的答案是这样的:
def my_split(s, sign): s = [s] for i in sign: t = [] for x in s: map(lambda x: t.extend(x.split(i)), s) s = t return sprint(my_split(s,sign))
按这逻辑推导了一遍,觉得这map, lambda用得高明,但是我一运行,结果竟然是[],什么鬼,说好的分割呢,全割没了?
难道编辑器有问题?难道我写错代码了,都不是,又重新推导了一遍,问题依旧!
然后我就按这种逻辑,自定义了一个函数,只不过没用map, lambda来实现:
def my_split(s, sign): for i in sign: t = [] if type(s) is list: for j in s: t.extend(j.split(i)) else: s = s.split(i) t.extend(s) s = t return sprint(my_split(s,sign))
代码是啰嗦了点,但是能正常运行,得到我想要的结果:
['ab', 'cd', 'efg', 'hi', 'jkl', 'mn', 'opq', 'rst', 'uvw', 'xyz']
既然这样,那说明逻辑上没有问题啊,那为什么结果不对呢?
经过多方请教无果:
不得不重新一步一步推导,然后看到函数my_split内部的lambda函数,这种样式不禁想到了闭包。就做了下面这样一个尝试:
def my_split(s, sign): s = [s] for i in sign: t = [] for x in s: #map(lambda x: t.extend(x.split(i)), s) def lambd(i, t, x, s): map(t.extend(x.split(i)),s) lambd(i, t, x, s) # 注意这行,这里执行了lambd函数 s = t return sprint(my_split(s,sign))
这里将lambda函数那行注释掉,重新定义了一个lambd函数,做了两样的事,但是,因为加上了执行,最终我得到了想要的结果。
事实上,lambda函数也可以赋值给一个对象,如:splits=lambda x: t.extend(x.split(i)),最后通过调用这个splits函数,达到执行的目的
但这样就失去了lambda 匿名函数的作用,并且由于外面需要执行map方法,所以这里是无法完成的。
最后,要说的就是,如上面定义的lamdb函数一样,它引用了外部变量如i, t ,x,s,形成了闭包,但是,如果最后不调用lamdb(i,t,x,s),
每次只是产生 了一个函数对象,并没有执行。
这里可以做这样一个测试:
def my_split(s, sign): s = [s] for i in sign: t = [] #map(lambda x: t.extend(x.split(i)), s) for x in s: def lambd(i, t, x, s): map(t.extend(x.split(i)),s) #lambd(i, t, x, s) # 注释掉 s = t print(s) # 打印出来 return sprint(my_split(s,sign))
我们将函数执行语句注释掉,然后每次内循环完成的时候打印s,结果发现每次s都是空列表。原因是lambd函数没有执行,
所以t列表一直为空,每次内循环执行完成后,将t赋值给了s,导致s也一直为空,这就是为什么最后得到的结果为空的原因。
这种lambda函数形成闭包比较隐蔽,如果没仔细看,很容易忽略,所以一定要注意。
当然这里更简单的办法是用正则表达式的re.split方法,一下字就可以搞定。
转载来自于:
http://www.cnblogs.com/Andy963/p/7043718.html
- lambda 函数所引起的闭包问题
- 升级那点事情-升级接口包所引起的一些问题
- 线程的并发所引起的问题
- 野指针所引起的问题
- 野指针所引起的问题
- jsessionid所引起的问题和解决
- jsessionid所引起的问题 和解决
- jsessionid所引起的问题 和解决
- java split函数中由于正则表达式所引起的问题
- c++中类对象直接作为函数参数所引起的问题。
- led驱动中未实现brightness_get函数所引起的问题。
- 闭包所带来的问题
- C++11闭包函数:Lambda表达式的使用λ
- 闭包函数 和 匿名lambda函数
- 函数、闭包及匿名函数(Lambda)
- [js点滴]javaScript闭包引起的问题及分析
- imagecreatefrompng函数引起的问题
- 一个包冲突引起的问题
- NTFS文件系统详解(一)之硬盘基本信息
- Ubuntu下python环境搭建
- mysql 输出表的详细信息 show table status like '表名'
- Centos7中firewall基本应用
- 打印所有不超过256,其平方具有对称性质的数(也称回文数,例如22的平方是484, 484是回文数。则打印22 和484)。
- lambda 函数所引起的闭包问题
- 36.开源项目--git搭建本地Git服务器
- c++内存映射初学
- MySQL--在批处理中执行SQL
- Android Studio中导入SlidingMenu(详解)
- 计算机视觉简介:历史、现状和发展趋势
- mysql 命令备忘
- ccf-csp
- LAMP环境搭建与配置(一)