增强型赋值语句是经常被使用到的,因为从各种学习渠道中,我们能够得知 i += 1 的效率往往要比 i = i + 1 更高一些(这里以 += 为例,实际上增强型赋值语句不仅限于此)。

所以我们会乐此不疲的在任何能够替换普通赋值语句的地方使用增量型赋值语句,以此来优化代码。那么我们是否有想过,在什么情况下 i += 1 其实并不等效于 i = i + 1 !!

例一:使用增强型赋值语句:

 In [1]: a = [1, 2, 3]
In [2]: b = a
In [3]: b += [1, 2, 3]
In [4]: print a, b
[1, 2, 3, 1, 2, 3] [1, 2, 3, 1, 2, 3]
In [5]: id(a), id(b)
Out[5]: (140213762276096, 140213762276096)

例二:使用普通赋值语句:

 In [6]: a = [1, 2, 3]
In [7]: b = a
In [8]: b = b + [1, 2, 3]
In [9]: print a, b
[1, 2, 3] [1, 2, 3, 1, 2, 3]
In [10]: id(a), id(b)
Out[10]: (140213762466232, 140213762276168)

上述两个例子中,将一个列表类型对象赋值给变量 a,再将变量 a 赋值给变量 b,此时 a、b 指向了同一个内存对象 [1, 2, 3]。

然后分别应用增量赋值运算符和普通赋值运算符来操作变量 b。

从最后的结果来看,例一中的 a、b 在进行运算后依旧指向了同一个内存对象。

例二则相反,a、b 分别指向了不同的内存对象,也就是说在例二中隐式的新建了一个内存对象。

这是一个值得注意的坑,警惕我们在使用增量赋值运算符来操作可变对象(如:列表)时可能会产生不可预测的结果。

要解释这个问题,首先需要了解「Python 共享引用」的概念:在 Python 中,允许若干个不同的变量引用指向同一个内存对象。

同时在前文中也提到,增强赋值语句比普通赋值语句的效率更高,这是因为在 Python 源码中, 增强赋值比普通赋值多实现了“写回”的功能,

也就是说增强赋值在条件符合的情况下(例如:操作数是一个可变类型对象)会以追加的方式来进行处理,而普通赋值则会以新建的方式进行处理。

这一特点导致了增强赋值语句中的变量对象始终只有一个,Python 解析器解析该语句时不会额外创建出新的内存对象。

所以例一中变量 a、b 的引用在最后依旧指向了同一个内存对象;相反,对于普通赋值运算语句,

Python 解析器无法分辨语句中的两个同名变量(例如:b = b + 1)是否应该为同一内存对象,所以干脆再创建出一个新的内存对象用来存放最后的运算结果,

所以例二中的 a、b 从原来指向同一内存对象,到最后分别指向了两个不同的内存对象。

​这是一个不为人所熟知的问题,我们能得到的结论就是:尽量不要使用增量赋值运算符来处理任何可变类型对象,除非你对上述问题有了足够的了解。

转自:http://blog.csdn.net/jmilk https://blog.csdn.net/Jmilk/article/details/78663744

【转】什么时候 i = i + 1 并不等于 i += 1?的更多相关文章

  1. 为什么 NaN 不等于自身?

    NaN 即Not a Number , 不是一个数字, 那么NaN到底是什么呢? 话说在JavaScript中,有6大数据类型,分别包括string,number,boolean,undefined, ...

  2. mybatis : trim标签, “等于==”经验, CDATA标签 ,模糊查询CONCAT,LIKE

    一.My Batis trim标签有点类似于replace效果. trim 属性, prefix:前缀覆盖并增加其内容 suffix:后缀覆盖并增加其内容 prefixOverrides:前缀判断的条 ...

  3. java中的等于

    数字的比较等于用“==” 不等于用“!=” 字符的比较等于用“.equals”不等于用”!s1.equals(s2)“

  4. mytatis将Integer等于0识别成空字符串

    在进行myBatis条件查询的时候,会有如下操作: <if test="delFlag !=null and delFlag != ''"> and t.del_fla ...

  5. js判断变量是否等于undefined

    js中判断变量是否等于undefined,不是使用==,而是使用typeof. typeof(featureId)!="undefined"

  6. css中的1px并不总等于设备的1px(高分辨率不等 低分辨等)

    在css中我们一般使用px作为单位,在桌面浏览器中css的1个像素往往都是对应着电脑屏幕的1个物理像素,这可能会造成我们的一个错觉,那就是css中的像素就是设备的物理像素.但实际情况却并非如此,css ...

  7. 深入理解JavaScript系列:为什么03-0.2不等于0.1

    五一宅家看书,所以接着更新一篇文章. 今天讲一下为什么03-0.2不等于0.1这个问题. 有点标题党的味道,在JavaScript中,当你试着对小数进行加减运算时,有时候会发现某个结果并非我们所想的那 ...

  8. 1不等于1?numeric、decimal、float 和 real 数据类型的区别

    大家有没有在SQL中遇见1不等于1(1<>1)的情形!?下面会有一个例子演示这个情形. 先简单介绍一下标题中的四种数值数据类型. 在T-SQL中,numeric和decimal是精确数值数 ...

  9. 关于sql用<>不等于查询数据不对问题

    平常查询数据 ' 当想要查询 不等于1 的数据的时候,一般会这样查询 ' 此处查询结果没查到所有想要的结果,如果night_flag 列数据为 null时,此行数据是查询不到的. 解决方法一: ' 解 ...

  10. 【编程题目】输入两个整数 n 和 m,从数列 1,2,3.......n 中 随意取几个数, 使其和等于 m ... ★

    第 21 题(数组)2010 年中兴面试题编程求解:输入两个整数 n 和 m,从数列 1,2,3.......n 中 随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来. 我的思路: 从小 ...

随机推荐

  1. K8S使用入门-创建第一个容器

    前面两个教程我们已经使用kubekit将K8S搭建起来了.但是,没有将实际使用中需要在K8S上部署我们的容器创建起来的教程,都是耍流氓.所以,经过几番折腾,我回来给自己洗白了.之前一直卡在创建第一个容 ...

  2. mysql数据库每天备份

    以备份mysql下的test数据库为例,备份到/home/data 使用mysqldunp命令 dump.sh mysqldump -h127. -uadmin -P3306 -ppassword t ...

  3. 【layui】获取layui弹窗的index并关闭

    var index = parent.layer.getFrameIndex(window.name); //获取窗口索引 parent.layer.close(index); // 关闭当前laye ...

  4. Delphi 开发微信公众平台 (三)- 获取微信服务器IP地址

    如果公众号基于安全等考虑,需要获知微信服务器的IP地址列表,以便进行相关限制,可以通过该接口获得微信服务器IP地址列表或者IP网段信息. 接口调用请求说明 http 请求方式: GET https:/ ...

  5. springboot2.x 使用redis (入门)

    在使用之前先简单介绍一下,redis和mongoDB这两个nosql的区别以及使用场景. 1. redis redis是一个分布式缓存.高性能的key-value数据库.支持存储的value类型包括s ...

  6. Shell编程学习(七)

    if 条件语句的知识与实践 if 条件语句 if条件语句的语法 单分支结构 第一种 if <条件测试表达式> then 指令 fi 第二种 if <条件测试表达式>; then ...

  7. NOI2019 退役记

    最终还是在意料之中退役了. 总的来说,这一年确实曲折坎坷,曾踏足山巅,也曾陷入低谷,二者都让我受益良多. 没有太多不甘,水平已经正常发挥,哪敢还有一丝奢求. 省选时其实已经早就做好退役的准备了,但命运 ...

  8. yii框架里DetailView视图和GridView的区别

    1,首先从语义上分析 DetailView是数据视图,用于显示一条记录的数据,相当于网页中的详情页 GridView是网格视图,用于显示数据表里的所有记录,相当于网页里的列表页 2.用法上的区别 首先 ...

  9. C# Datatable、DataReader等转化json

    //对象转换为Json字符串 public static string ToJson(object jsonObject) { object objectValue = string.Empty; s ...

  10. .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化

    原文:.NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化 最近我大幅度重构了我一个库的项目结构,使之使用最新的项目文件格式(基于 Microsoft.NET.Sdk)并使 ...