鱼C论坛

 找回密码
 立即注册
查看: 2819|回复: 18

[已解决]如何更好理解list中的+= ?死记硬背吗

[复制链接]
发表于 2022-10-10 17:35:52 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 jcpython2 于 2022-10-10 17:37 编辑

list中 a += b 和 a = a+ b不同,这个平时稍有不注意就当成一样的了,如何更好理解这个点? 靠死记硬背吗?   我经常在其他非list用法把 x +=y 当成  x = x +y





b = a = [1,2]

a += [3] #ab指向同一个地方,在a末尾添加元素,b也受影响

》》[1,2,3] [1,2,3]

a = a + [4,5]   #对a重新赋值,不会影响到b

print(a,b)
》》[1,2,3,4,5] [1,2,3]
最佳答案
2022-10-10 21:05:16
本帖最后由 阿奇_o 于 2022-10-10 21:11 编辑

关键1:搞清楚 操作的是什么对象 —— 具体什么操作? 针对哪个对象?
           以你提到的 a = a + [4,5]  和 a += [3] 的不同之处:
           前者是 两个列表的相加操作,会返回新的列表对象;后者是 “扩展运算符”或叫“增量赋值运算符” 的运算操作,是就地改变原来的a
           (等到学到OOP且比较深入时,你就会了解 定义一个python对象时,如果实现 __add__ 就可以自定义相加的行为和返回,而 __iadd__ 就可以自定义后者 += 的行为和返回)
  1. a = b = [1,2]
  2. id(a) == id(b)
  3. True
  4. id(a)
  5. 2556956942336
  6. a += [3]
  7. id(a)
  8. 2556956942336
  9. a
  10. [1, 2, 3]
  11. a = a + [3]
  12. id(a)
  13. 2556988297344
  14. a
  15. [1, 2, 3, 3]
  16. id(b)
  17. 2556956942336
  18. id(a) == id(b)
  19. False
  20. b
  21. [1, 2, 3]
复制代码


关键2:对象 到底是什么? 为什么说你看不见它,却可以 调用/使用 它?
              - 为什么我对象可以叫a,b,c,x,y,z, 可以叫 小兰,也可以叫 亲爱的? —— 唤之以名。(可 叫它,叫它"老婆" 它就一定会来吗,一定会满足你的要求吗?)
              - 对象的类型type 不同会对各种操作有什么影响?(你对象是男是女的?对生娃肯定又影响!如 list就是“可变的”,str, tuple就是“不可变的”。)
              - 对象的id, id(obj) 是什么?有什么用? (你对象是不是你的“唯一”?  。。哈哈哈)
              - 对象的value,可以看做 值,延伸出来就是 属性和方法。  (你对象的颜值多少?身高多少?会做饭么?... )

ps: 关于对象的具体代码例子,我懒得敲了,我以前回答的帖子,已经举出足够多了。。


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-10-10 17:36:44 | 显示全部楼层
因为小甲鱼教程中一开始强调的一段是 指向  

然后到了list就有点不一样了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-10-10 18:11:56 | 显示全部楼层
  1. b=a = [1,2,3,4,5]

  2. c = a * 3
  3. print(c)
  4. c = [a] *3
  5. print(c)
复制代码

  1. [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
  2. [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]
复制代码



想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-10 18:27:57 | 显示全部楼层
        a += b 就是  a = a + b 列表也不例外
        看看这个,有什么疑问吗?
  1. >>> a = [1 , 2 , 3]
  2. >>> b = [4 , 5 , 6 , 7]
  3. >>> c = a[:]
  4. >>> d = b[:]
  5. >>> a += b
  6. >>> a
  7. [1, 2, 3, 4, 5, 6, 7]
  8. >>> c = c + d
  9. >>> c
  10. [1, 2, 3, 4, 5, 6, 7]
  11. >>> b
  12. [4, 5, 6, 7]
  13. >>> d
  14. [4, 5, 6, 7]
  15. >>>
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-10 21:05:16 | 显示全部楼层    本楼为最佳答案   
本帖最后由 阿奇_o 于 2022-10-10 21:11 编辑

关键1:搞清楚 操作的是什么对象 —— 具体什么操作? 针对哪个对象?
           以你提到的 a = a + [4,5]  和 a += [3] 的不同之处:
           前者是 两个列表的相加操作,会返回新的列表对象;后者是 “扩展运算符”或叫“增量赋值运算符” 的运算操作,是就地改变原来的a
           (等到学到OOP且比较深入时,你就会了解 定义一个python对象时,如果实现 __add__ 就可以自定义相加的行为和返回,而 __iadd__ 就可以自定义后者 += 的行为和返回)
  1. a = b = [1,2]
  2. id(a) == id(b)
  3. True
  4. id(a)
  5. 2556956942336
  6. a += [3]
  7. id(a)
  8. 2556956942336
  9. a
  10. [1, 2, 3]
  11. a = a + [3]
  12. id(a)
  13. 2556988297344
  14. a
  15. [1, 2, 3, 3]
  16. id(b)
  17. 2556956942336
  18. id(a) == id(b)
  19. False
  20. b
  21. [1, 2, 3]
复制代码


关键2:对象 到底是什么? 为什么说你看不见它,却可以 调用/使用 它?
              - 为什么我对象可以叫a,b,c,x,y,z, 可以叫 小兰,也可以叫 亲爱的? —— 唤之以名。(可 叫它,叫它"老婆" 它就一定会来吗,一定会满足你的要求吗?)
              - 对象的类型type 不同会对各种操作有什么影响?(你对象是男是女的?对生娃肯定又影响!如 list就是“可变的”,str, tuple就是“不可变的”。)
              - 对象的id, id(obj) 是什么?有什么用? (你对象是不是你的“唯一”?  。。哈哈哈)
              - 对象的value,可以看做 值,延伸出来就是 属性和方法。  (你对象的颜值多少?身高多少?会做饭么?... )

ps: 关于对象的具体代码例子,我懒得敲了,我以前回答的帖子,已经举出足够多了。。


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2022-10-10 22:39:03 | 显示全部楼层
jackz007 发表于 2022-10-10 18:27
a += b 就是  a = a + b 列表也不例外
        看看这个,有什么疑问吗?

我没说清楚缘由,看我下面两段代码,输出不一样

  1. b = a = [1,2]

  2. a += [4,5]
  3. print(a)
  4. print(b)
复制代码


[1, 2, 4, 5]
[1, 2, 4, 5]   



第二段代码
  1. b = a = [1,2]

  2. a = a + [4,5]
  3. print(a)
  4. print(b)
复制代码


[1, 2, 4, 5]
[1, 2]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-10-10 22:39:38 | 显示全部楼层
阿奇_o 发表于 2022-10-10 21:05
关键1:搞清楚 操作的是什么对象 —— 具体什么操作? 针对哪个对象?
           以你提到的 a = a + [4, ...

我先消化下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-10-10 23:53:04 | 显示全部楼层
jackz007 发表于 2022-10-10 18:27
a += b 就是  a = a + b 列表也不例外
        看看这个,有什么疑问吗?

还比如这个
b c 各= 了a

b 成了新列表
c 挂在a那头随a变动

  1. a = [1,2,3]
  2. b = a *3
  3. c = [a] * 3

  4. a[1] = '99'
  5. print(a)
  6. print(b)
  7. print(c)
复制代码

  1. [1, '99', 3]
  2. [1, 2, 3, 1, 2, 3, 1, 2, 3]
  3. [[1, '99', 3], [1, '99', 3], [1, '99', 3]]
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-10-11 13:39:49 | 显示全部楼层
本帖最后由 jcpython2 于 2022-10-11 13:40 编辑
阿奇_o 发表于 2022-10-10 21:05
关键1:搞清楚 操作的是什么对象 —— 具体什么操作? 针对哪个对象?
           以你提到的 a = a + [4, ...


53.jpg

简单归纳了下,应该算是弄懂了点,但还没学到python的对象内容


顺便做了一道题,自己家的注释,有没有理解错
  1. b = [0]
  2. a = [b] *2 + [b] *2  #a重新赋值为[b] * 2,b后期变动不影响a,
  3.                      # 前面的 [b] * 2的值与后面[b] * 2的值相同,并且指向同一内存,修改变动跟随
  4.                      #a[[0],[0]]等于第二行第一部分[b]*2结果,指向同一内存,所以a[0][0]变动后
  5.                      #a[[0],[0],[0],[0]]所有[0]均变动为[5]
  6. a[0][0] = [5]        #
  7. print(a)
  8. print((a[0][0]))

  9. b = [99]             #a已经指向其他内存,b变动不影响
  10. print(b)
复制代码

  1. [[[5]], [[5]], [[5]], [[5]]]
  2. [5]
  3. [99]
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-10-11 22:26:39 | 显示全部楼层
本帖最后由 jcpython2 于 2022-10-11 22:29 编辑
阿奇_o 发表于 2022-10-10 21:05
关键1:搞清楚 操作的是什么对象 —— 具体什么操作? 针对哪个对象?
           以你提到的 a = a + [4, ...


图片12.png

11222420.jpg


如上图所示,我的想法是+ *都是运算符,为什么*得出了新地址,+没有发挥相同作用呢(图1),就如我图一那样,为什么a = [[0]] * 2 + [[0]] *2后出来两个内存地址,而不是一个呢? + 有特别意义?


比如
a = [1,2,3]
a *= 5
无错

a = [1,2,3]
a += 5

因为+在这里不是加,是‘拼接’这样理解对吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-12 14:10:10 | 显示全部楼层
本帖最后由 阿奇_o 于 2022-10-12 14:14 编辑

你看不懂中文,或阅读理解有问题,或者 现在因为你背景知识不足,无法全部理解。 学完面向对象编程OOP部分,再回过头看看吧。

就简单说一下, 就是要区分 不同的操作  会产生 就地修改,还是返回新的对象

    a *= 5 或其他 +=,-=,/= 等是 “增量赋值算术运算符” ,会 就地修改。这种等价于 a.__imul__(5) , a.__iadd__(b) 等 (就是调用了对象的特定的特殊方法)。

    a = a * 5 或其他  +,- ,/ 等是 一般的 “算术运算符” 都是 返回新的对象,并与字符a绑定(重新赋值)。 这等价于 如  a.__mul__(5) , a.__add__(b)   

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
jcpython2 + 1 + 1 感谢楼主无私奉献!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-10-12 14:35:53 | 显示全部楼层
阿奇_o 发表于 2022-10-12 14:10
你看不懂中文,或阅读理解有问题,或者 现在因为你背景知识不足,无法全部理解。 学完面向对象编程OOP部分 ...

是的,我的环境比较差,学习背景也几乎没有,无论从教程文字还是数学理论都是在硬吃的阶段,比较苦,所以一旦涉及到疑问卡主都是反复尝试后才敢来论坛提问,很多时候什么我没办法解释到疑点,也是比较吃力,有时候甚至要背代码,求逻辑搞不清的时候,起码不会写错代码,方便排查
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-12 14:38:59 | 显示全部楼层
  1. >>> a = b =[1]
  2. >>> id(a)
  3. 53038856
  4. >>> id(b)
  5. 53038856
  6. >>> a += [2]
  7. >>> a
  8. [1, 2]
  9. >>> id(a)
  10. 53038856
  11. >>> id(b)
  12. 53038856
  13. >>> c = d = [1]
  14. >>> id(c)
  15. 53055592
  16. >>> id(d)
  17. 53055592
  18. >>> c = c + [1]
  19. >>> c
  20. [1, 1]
  21. >>> d
  22. [1]
  23. >>> id(c)
  24. 53038664
  25. >>> id(d)
  26. 53055592
复制代码


我理解的是‘a +=[1]’    a和b 2个变量指向同一的内存地址。一个变动另外一个也变动,因为列表本身就是可以变的
c = c+[1]  这个是算数运算符,相当于c重新赋值了,但是d还是指向原来的内存地址

评分

参与人数 1荣誉 +1 收起 理由
jcpython2 + 1 感谢楼主无私奉献!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-12 14:40:06 | 显示全部楼层
还有你说的+和* 不同 你应该去看一下嵌套列表,那里有详细的讲这个问题,还有列表拷贝的问题.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-12 16:22:05 | 显示全部楼层
本帖最后由 阿奇_o 于 2022-10-12 16:23 编辑
jcpython2 发表于 2022-10-12 14:35
是的,我的环境比较差,学习背景也几乎没有,无论从教程文字还是数学理论都是在硬吃的阶段,比较苦,所以 ...


没事,【认清现实,笃信成长】就好,我也是一学渣大专生。 基础差点,就慢慢来。
-入门推荐:
   - 《计算机是怎样跑起来的》、《计算机科学导论》 背景知识、硬件知识、整体了解CS
   -《Think Python》《Python修炼之道》以及 多看看《官方文档》(特别是Howto系列)等。
   -《Python GUI设计——tkinter菜鸟编程》

-进阶推荐:
   -《Fluent Python》《Python Cookbook》等
   - 算法,设计模式,等等。

-数据分析向 肯定要推:
    -《用Python进行数据分析》Python For Data Analysis(可以第一版中文为主,第二版英文为辅助)

-爬虫方向 :
   -《Python3网络爬虫开发实战》入门与进阶

另外,多用善用搜索,顺便用熟英文,认认真真啃书,老老实实敲代码 —— 成长必然
—— 最后 死而无憾。 共勉。

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
jcpython2 + 1 + 1 共勉

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-10-12 17:00:08 | 显示全部楼层
阿奇_o 发表于 2022-10-12 16:22
没事,【认清现实,笃信成长】就好,我也是一学渣大专生。 基础差点,就慢慢来。
-入门推荐:
   -  ...

我现在其实自己感觉最大的问题就是只会死记硬背,我在牛客网把入门题都刷遍了,刷完又看了别人的答案,别人的写法让我茅塞顿开,感觉这一种方式让我成长很快,现在我是学一章节就把牛客网力扣小甲鱼的课后作业相关内容刷了,面试题还遥不可及这两天在看书,就嗑书的例子,你说的Python Cookbook也有了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-10-12 17:02:16 | 显示全部楼层
简单滴滴 发表于 2022-10-12 14:38
我理解的是‘a +=[1]’    a和b 2个变量指向同一的内存地址。一个变动另外一个也变动,因为列表本身就 ...

我一开始也是这么简单想的,做了两道题就开始乱了

比如下面这题猜print a得出啥,我这个贴就是这个题引发的
  1. a = [[0]] * 2 + [[0]] *2
  2. a[0][0] = 5
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-12 17:32:19 | 显示全部楼层
jcpython2 发表于 2022-10-12 17:02
我一开始也是这么简单想的,做了两道题就开始乱了

比如下面这题猜print a得出啥,我这个贴就是这个题 ...
  1. a = [[0]] * 2 + [[0]] *2
复制代码


里面的2个[0]*2不是一个对象,虽然他们看起来一样
  1. >>> a = [0]*2
  2. >>> b = [0]*2
  3. >>> id(a)
  4. 43925800
  5. >>> id(b)
  6. 43775240
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-10-12 17:49:24 | 显示全部楼层
简单滴滴 发表于 2022-10-12 17:32
里面的2个[0]*2不是一个对象,虽然他们看起来一样

我一开始也明白他们只是看着一样,但并不是同一对象

我当初迷惑的是第一段输出是[[0], [0], [0], [0]]

我一开始以为前面的[0]都是独立的,因为我眼中 + *一样,既然+独立了*也是独立

所以卡主了好久好久
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-20 13:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表