摘要:在做数据处理的时候碰到一个奇怪的现象大兴大兴大兴大兴大兴大兴大兴发现这个列表里的每个元素都是一样的检查循环里的和一切正常循环里的就不太正常朝阳海淀海淀昌平昌平昌平丰台丰台丰台丰台西城西城西城西城西城部分数据是这样的发生了的操作但列表里所有元
在做数据处理的时候, 碰到一个奇怪的现象.
for tuple in list.most_common(): dict["name"] = tuple[0] dict["value"] = tuple[1] d1.append(dict) print(d1)
[{"name": "大兴", "value": 32}, {"name": "大兴", "value": 32}, {"name": "大兴", "value": 32}, {"name": "大兴", "value": 32}, {"name": "大兴", "value": 32}, {"name": "大兴", "value": 32}, {"name": "大兴", "value": 32}]
发现d1这个列表里的每个元素都是一样的. 检查循环里的tuple 和 dict 一切正常.
循环里的d1 就不太正常...
for tuple in list.most_common(): dict["name"] = tuple[0] dict["value"] = tuple[1] d1.append(dict) print(d1)
[{"name": "朝阳", "value": 102}]
[{"name": "海淀", "value": 65}, {"name": "海淀", "value": 65}]
[{"name": "昌平", "value": 53}, {"name": "昌平", "value": 53}, {"name": "昌平", "value": 53}]
[{"name": "丰台", "value": 53}, {"name": "丰台", "value": 53}, {"name": "丰台", "value": 53}, {"name": "丰台", "value": 53}]
[{"name": "西城", "value": 48}, {"name": "西城", "value": 48}, {"name": "西城", "value": 48}, {"name": "西城", "value": 48}, {"name": "西城", "value": 48}]
部分数据是这样的. 发生了append的操作, 但列表里所有元素的值都一样. 为什么会这样?
几个小时后, 想到了一种可能性. 在append操作的时候, 传入的是一个引用, 导致后期dict变化, 前面元素的值也跟着变化. 解决方法是传入一个dict的copy, 传一个值, 而不是引用.
修改后的代码:
for tuple in list.most_common(): dict["name"] = tuple[0] dict["value"] = tuple[1] d = copy.copy(dict) d1.append(d) print(d1)
[{"name": "朝阳", "value": 102}, {"name": "海淀", "value": 65}, {"name": "丰台", "value": 53}, {"name": "昌平", "value": 53}, {"name": "西城", "value": 48}, {"name": "通州", "value": 36}, {"name": "大兴", "value": 32}, {"name": "东城", "value": 22}, {"name": "顺义", "value": 18}, {"name": "石景山", "value": 16}, {"name": "NULL", "value": 11}, {"name": "房山", "value": 7}, {"name": "门头沟", "value": 6}, {"name": "燕郊", "value": 5}, {"name": "亦庄开发区", "value": 3}]
ok, 确实是假想的那样, 传引用产生的问题, 加上一个拷贝语句就可以了. 可是之前也做过不少的利用append来构造字典数组的案例, 从没碰到过问题, 也没有添加过拷贝. 仔细观察之下, 发现我的 dict= {} 声明是放在for循环外的. 那这应该就是问题所在了.
再次修改后的代码:
for tuple in list.most_common(): # 把dict的定义放入 for 循环内 dict = {} dict["name"] = tuple[0] dict["value"] = tuple[1] # d = copy.copy(dict) d1.append(dict) print(d1)
总结一下, 由于疏忽把dict= {}放在for循环外, 在append的时候, 一直添加的是同一个dict的引用, dict 内的值变化, 引起了列表内所有元素的变化.
在最后的修改里, 每一次循环, 都会新建一个空字典, 每次循环 dict 都是一个独立的值. 正确的做法也应该是这样的.
PS: 尝试了一下, Js的arr.push(obj) 也有同样的问题, 当然有良好编码习惯的人是不会碰到这种问题的.
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/41747.html
摘要:说明一下里函数传的是值还是引用答案是都传。如果传入的参数是简单类型,如和,那么传入的就是值。如果是对象和数组,在函数里做的操作就会影响到函数外边。举几个栗子结语提问和纠错请留言。 说明一下 JavaScript里函数传的是值还是引用?答案是都传。如果传入的参数是简单类型,如String和Number,那么传入的就是值。但如果你传入的是Object和Array,那么就是引用。 这就意...
摘要:引用类型参数的传递与引用类型的复制一样,传递的是内存地址。指向一个新的地址,与不再指向同一个地址官方解释来一发中所有函数的参数都是按值传递的。总结很简单,函数参数都是按值传递都是栈内数据的拷贝。 基本类型与引用类型 值类型(基本类型):String,Number,Boolean,Null,Undefined。 引用类型:Array、Object、Function、Date等有多个值...
摘要:引用类型参数的传递与引用类型的复制一样,传递的是内存地址。指向一个新的地址,与不再指向同一个地址官方解释来一发中所有函数的参数都是按值传递的。总结很简单,函数参数都是按值传递都是栈内数据的拷贝。 基本类型与引用类型 值类型(基本类型):String,Number,Boolean,Null,Undefined。 引用类型:Array、Object、Function、Date等有多个值...
阅读 1147·2021-11-15 18:14
阅读 3613·2021-11-15 11:37
阅读 728·2021-09-24 09:47
阅读 2370·2021-09-04 16:48
阅读 2168·2019-08-30 15:53
阅读 2366·2019-08-30 15:53
阅读 373·2019-08-30 11:20
阅读 1215·2019-08-29 16:08