python易错盲点排查之+=与+的区别分析以及一些赋值运算踩过的坑[通俗易懂]

python易错盲点排查之+=与+的区别分析以及一些赋值运算踩过的坑

大家好,又见面了,我是全栈君。

问题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)

 

转载于:https://www.cnblogs.com/ECJTUACM-873284962/p/8530459.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/107664.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 晴天的魔法乐园——谢尔宾斯基地毯(递归打印图形)「建议收藏」

    晴天的魔法乐园——谢尔宾斯基地毯(递归打印图形)「建议收藏」题目链接:https://judger.net/problem/1061ProblemDescription谢尔宾斯基地毯是一种分形图案,它的定义如下:令F(n)表示嵌套n层的谢尔宾斯基地毯,那么(下面的“空”均表示空格,仅为示意,实际输出时应仍为空格)当n=1时,F(1)为:空当n=2时,F(2)为:空空空空X空空空空一般地,如果F(n-1)表示嵌…

    2022年7月13日
    13
  • 卸载MySQL Connector NET无法卸载

    卸载MySQL Connector NET无法卸载卸载MySQLConnectorNET无法卸载最近安装了MYSQL数据库,安装完发现安装在了系统C盘,对于文件整理控加一丢丢强迫症的我来说,太介意了,不能忍。这里是解决办法:安装MYSQL自定义路径方法于是,开始卸载MYSQL,结果,ConnectorNET始终卸载不掉。网上看到了很多方法,删文件删注册表都无济于事,丝毫没有成功。终于,在google里找到可行的解决方法。原文网址:Cannotuninstall/repair/ChangeMySQL-Connector-net?Iss

    2022年7月15日
    25
  • HTTP 500 Internal Server Error[通俗易懂]

    HTTP 500 Internal Server Error[通俗易懂]HTTP500InternalServerError

    2022年7月14日
    13
  • 基于单片机的功放protues_基于Proteus的音频放大器电路设计与仿真详解.doc[通俗易懂]

    基于单片机的功放protues_基于Proteus的音频放大器电路设计与仿真详解.doc[通俗易懂]毕业论文学生姓名尹有友学号171107078学院物理与电子电气工程学院专业电子信息工程题目基于Proteus的音频放大电路设计与仿真指导教师付浩副教授/学士2015年5月论文原创性声明内容本人郑重声明:本论文是我个人在导师指导下进行的研究工作及取得的研究成果。本论文除引文外所有实验、数据和有关材料均是真实的。尽我所知,除了文中特别加以标注和致谢的地方外…

    2022年6月6日
    34
  • 如何解决Intel SCS “Can not create AD AMT Object” error

    如何解决Intel SCS “Can not create AD AMT Object” error

    2022年3月8日
    46
  • mysql版本查询命令「建议收藏」

    mysql版本查询命令「建议收藏」mysql版本查询命令有:1、输入“selectversion();”命令,按回车键,即可查看当前mysql版本;2、输入“status”命令,按回车键,即可查看当前mysql版本。在我们的电脑上打开mysql控制台,输入密码进去方法一:输入“selectversion();”命令,按回车键,可以看到mysql的版本号方法二:可以输入“status”命令,按回车键,看到mysql的版本号是8.0.28…

    2022年9月25日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号