鱼C论坛

 找回密码
 立即注册
查看: 1820|回复: 7

[已解决]一个诡异现象,百思不得其解,望大神帮助

[复制链接]
发表于 2017-8-21 18:26:25 | 显示全部楼层 |阅读模式

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

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

x
为什么下面代码运行结果不是我想要的[{desc:1,link:11},{desc:2,link:12},{desc:3,link:13}],
而是非常奇怪的结果[{desc:3,link:13},{desc:3,link:13},{desc:3,link:13}]

求指点帮助谢谢

  1. p=[1,2,3]
  2. q=[11,12,13]
  3. items=[]
  4. item={}

  5. for i in range(len(p)):
  6.     item['desc']=p[i]
  7.     item['link']=q[i]
  8.     items.append(item)

  9. print(items)
复制代码
最佳答案
2017-8-21 19:17:44
这是python可变变量的一个坑。什么是可变变量,用最简单的话说就是内容改变而地址不变。详细的就不论述了,以后有机会单开帖吧。
item={}的确良一个地址,就叫它地址1吧。
第一次循环items为[地址1],这时地址1的内容为{desc:1,link:11}
第二次循环items为[地址1, 地址1],这时地址1的内容为{desc:2,link:12}
第三次循环items为[地址1, 地址1, 地址1],这时地址1的内容为{desc:3,link:13}
这样就得到你现在的结果。
如果你想得到预期的结果,这样改一下。
  1. p=[1,2,3]
  2. q=[11,12,13]
  3. items=[]
  4. item={}

  5. for i in range(len(p)):
  6.     item = {'desc':p[i],'link':q[i]}
  7.     items.append(item)
  8. print(items)
复制代码

对可变变量整体重新赋值则相当于不可变变量,会采用一个新的地址。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-8-21 18:30:10 | 显示全部楼层
这就是Python一诡异之处
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-21 18:32:21 | 显示全部楼层
求帮助
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-21 19:15:26 | 显示全部楼层
item只是记录了字典的地址,你每次添加的同一个地址,当然3个字典的内容都一样了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-21 19:17:07 | 显示全部楼层
2017-08-21_191438.png
  1. p=[1,2,3]
  2. q=[11,12,13]
  3. items=[]

  4. for i in range(len(p)):
  5.     item={}
  6.     item['desc']=p[i]
  7.     item['link']=q[i]
  8.     items.append(item)

  9. print(items)
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-21 19:17:44 | 显示全部楼层    本楼为最佳答案   
这是python可变变量的一个坑。什么是可变变量,用最简单的话说就是内容改变而地址不变。详细的就不论述了,以后有机会单开帖吧。
item={}的确良一个地址,就叫它地址1吧。
第一次循环items为[地址1],这时地址1的内容为{desc:1,link:11}
第二次循环items为[地址1, 地址1],这时地址1的内容为{desc:2,link:12}
第三次循环items为[地址1, 地址1, 地址1],这时地址1的内容为{desc:3,link:13}
这样就得到你现在的结果。
如果你想得到预期的结果,这样改一下。
  1. p=[1,2,3]
  2. q=[11,12,13]
  3. items=[]
  4. item={}

  5. for i in range(len(p)):
  6.     item = {'desc':p[i],'link':q[i]}
  7.     items.append(item)
  8. print(items)
复制代码

对可变变量整体重新赋值则相当于不可变变量,会采用一个新的地址。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-21 19:38:05 | 显示全部楼层
本帖最后由 zmx296689210 于 2017-8-21 19:39 编辑

举个例子:

  1. >>> dit = {'desc':1 , 'link':11}   # 一个字典
  2. >>> item = []  # 一个列表
  3. >>> item.append(dit)
  4. >>> item.append(dit)
  5. >>> item.append(dit)
  6. >>> item
  7. [{'desc': 1, 'link': 11}, {'desc': 1, 'link': 11}, {'desc': 1, 'link': 11}]
  8. >>> dit['desc'] = 2
  9. >>> item
  10. [{'desc': 2, 'link': 11}, {'desc': 2, 'link': 11}, {'desc': 2, 'link': 11}]
  11. >>> # 实际上, 列表每次往里面塞的都是 dit的地址, 所以三个列表元素的地址是一样的,一个改变了,另一个肯定也改变
  12. ... # 你所说的问题也是这个原因
  13. ...
  14. >>> id(item[0])
  15. 16785648
  16. >>> id(item[1])
  17. 16785648
  18. >>> id(item[2])
  19. 16785648
  20. >>>
复制代码



通过最后的id这个内置函数可以知道列表里面的元素的地址是相同的. 你所问的, 每次都是往里面塞入同一个字典地址, 且改变了地址里面的址,最后结果就是你得到的结果。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-22 08:30:14 | 显示全部楼层
感谢各位前辈的帮助,谢谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-3-1 17:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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