博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python易错盲点排查之+=与+的区别分析以及一些赋值运算踩过的坑
阅读量:6094 次
发布时间:2019-06-20

本文共 1702 字,大约阅读时间需要 5 分钟。

问题1. int和list是不一样的

 

>>> a=1>>> b=a>>> a+=1>>> a,b(2, 1)>>> a=[1,2,3,4]>>> b=a>>> a+=[5]>>> a,b([1, 2, 3, 4, 5], [1, 2, 3, 4, 5])

 

通俗地讲,类型为int时,a和b是“不一样的”;类型为list时,a和b是“一样的”。术语叫做immutable和mutable,具体原理在这个节点不必深究。

问题1.1. 我们通常运行b=a这一语句时,会直觉地认为,b和a已经不一样了。

>>> a=[[1],[2],[3],[4]]>>> b+=a[0:2]>>> b[1, 2, 3, 4, [1], [2]]>>> a=[[1],[2],[3],[4]]>>> b=[]>>> b+=a[0:2]>>> a,b([[1], [2], [3], [4]], [[1], [2]])>>> b[0][1]>>> b[0][0]='changed!'>>> # You don't expect a to change>>> # However>>> a, b([['changed!'], [2], [3], [4]], [['changed!'], [2]])

可以看到,a[0]的[1]和b[0]的[1]是“一样的”,因为改变b[0]就会改变a[0](注意不是改变b,是改变b[0]。改变b不会对a有任何影响)

问题2. list的情况下,a+=b和a=a+b是不一样的

>>> a=[1,2,3,4]>>> b=a>>> a+=[5]>>> a,b([1, 2, 3, 4, 5], [1, 2, 3, 4, 5])>>> a=[1,2,3,4]>>> b=a>>> a=a+[5]>>> a,b([1, 2, 3, 4, 5], [1, 2, 3, 4])

同样通俗地讲,在+=的情况下,a还是原来的a,和b“一样”;在+的情况下,a已经不是原来的a了,和b“不一样”。

问题3. 如果要让+=和+行为一致,应该怎么做?

>>> import copy>>> a=[1,2,3,4]>>> b=copy.deepcopy(a)>>> a+=[5]>>> a,b([1, 2, 3, 4, 5], [1, 2, 3, 4])

这与问题2中a=a+b的情况结果一致了。当对list进行b=a时,实际上进行的是“引用”操作;只有使用b=copy.deepcopy(a)才是进行我们通常期望的“拷贝”操作。

问题4. 回到问题中的代码,当k=1时,以下代码:

subset += (elements[0:size])

根据问题1.1,subset与elements是“一样的”,因此未来改变subset的元素的操作有可能改变elements的元素

到这行代码时,注意set就是递归传递过来的subset:

#set[j] +=  (elements[i])  #Why Elements change here?set[j]  = set[j] +  (elements[i])

根据问题2,+=中set[j]依然是原来的set[j],也就可能是elements的元素。因此

set[j] += elements[i]

可能会等价于

elements[*] += elements[i]

一旦改变了elements的元素,结果自然就不对了。

怎么解决这个问题?根据问题3,只要保证set与elements是“不一样的”,就符合程序的逻辑。因此将

subset += (elements[0:size])

改为(记得import copy)

subset += copy.deepcopy(elements[0:size])

就能在+=的情况下正常运行了。

总结:在python中,list类型的赋值b=a进行的引用操作,而非拷贝操作,在需要拷贝操作时,需要加上b=copy.deepcopy(a)。(copy.copy和copy.deepcopy的区别超出问题范畴,有兴趣可以google)

 

转载地址:http://duwza.baihongyu.com/

你可能感兴趣的文章
构建之法阅读笔记三
查看>>
Python/PHP 远程文件/图片 下载
查看>>
【原创】一文彻底搞懂安卓WebView白名单校验
查看>>
写给对前途迷茫的朋友:五句话定会改变你的人生
查看>>
并行程序设计学习心得1——并行计算机存储
查看>>
mysql练习题40道
查看>>
JAVA入门到精通-第86讲-半双工/全双工
查看>>
bulk
查看>>
js document.activeElement 获得焦点的元素
查看>>
abb画学号
查看>>
C++ 迭代器运算
查看>>
【支持iOS11】UITableView左滑删除自定义 - 实现多选项并使用自定义图片
查看>>
day6-if,while,for的快速掌握
查看>>
JavaWeb学习笔记(十四)--JSP语法
查看>>
【算法笔记】多线程斐波那契数列
查看>>
java8函数式编程实例
查看>>
jqgrid滚动条宽度/列显示不全问题
查看>>
在mac OS10.10下安装 cocoapods遇到的一些问题
查看>>
angularjs表达式中的HTML内容,如何不转义,直接表现为html元素
查看>>
css技巧
查看>>