目 录
一、问题再现
1、问题阐述
每次for循环过程中,列表中的所有字典值都和最新的字典赋值相同
2、python代码
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:bigbear
# datetime:2022/9/8 20:29
# software: PyCharm
t = {"tt": "DUCLAE"}
print(f"---t初始内存地址---{id(t)}")
list0 = [1, "33", 5, {"gg": "sad"}, [1, 2, 3]]
list1 = []
for n in list0:
t["tt"] = n
print(f"\t---t被赋值后内存地址---{id(t)}")
print(f"\t---t被赋值后字典---{t}")
list1.append(t)
for i, n1 in enumerate(list1):
print(f"\t---列表中第-{i + 1}-个内存地址---{id(n1)}")
print(f"\t---列表中第-{i + 1}-个字典---{n1}")
print(f"\t---list1---{list1}\n")
3、运行结果
---t初始内存地址---2090766940096
---t被赋值后内存地址---2090766940096
---t被赋值后字典---{'tt': 1}
---列表中第-1-个内存地址---2090766940096
---列表中第-1-个字典---{'tt': 1}
---list1---[{'tt': 1}]---t被赋值后内存地址---2090766940096
---t被赋值后字典---{'tt': '33'}
---列表中第-1-个内存地址---2090766940096
---列表中第-1-个字典---{'tt': '33'}
---列表中第-2-个内存地址---2090766940096
---列表中第-2-个字典---{'tt': '33'}
---list1---[{'tt': '33'}, {'tt': '33'}]---t被赋值后内存地址---2090766940096
---t被赋值后字典---{'tt': 5}
---列表中第-1-个内存地址---2090766940096
---列表中第-1-个字典---{'tt': 5}
---列表中第-2-个内存地址---2090766940096
---列表中第-2-个字典---{'tt': 5}
---列表中第-3-个内存地址---2090766940096
---列表中第-3-个字典---{'tt': 5}
---list1---[{'tt': 5}, {'tt': 5}, {'tt': 5}]---t被赋值后内存地址---2090766940096
---t被赋值后字典---{'tt': {'gg': 'sad'}}
---列表中第-1-个内存地址---2090766940096
---列表中第-1-个字典---{'tt': {'gg': 'sad'}}
---列表中第-2-个内存地址---2090766940096
---列表中第-2-个字典---{'tt': {'gg': 'sad'}}
---列表中第-3-个内存地址---2090766940096
---列表中第-3-个字典---{'tt': {'gg': 'sad'}}
---列表中第-4-个内存地址---2090766940096
---列表中第-4-个字典---{'tt': {'gg': 'sad'}}
---list1---[{'tt': {'gg': 'sad'}}, {'tt': {'gg': 'sad'}}, {'tt': {'gg': 'sad'}}, {'tt': {'gg': 'sad'}}]---t被赋值后内存地址---2090766940096
---t被赋值后字典---{'tt': [1, 2, 3]}
---列表中第-1-个内存地址---2090766940096
---列表中第-1-个字典---{'tt': [1, 2, 3]}
---列表中第-2-个内存地址---2090766940096
---列表中第-2-个字典---{'tt': [1, 2, 3]}
---列表中第-3-个内存地址---2090766940096
---列表中第-3-个字典---{'tt': [1, 2, 3]}
---列表中第-4-个内存地址---2090766940096
---列表中第-4-个字典---{'tt': [1, 2, 3]}
---列表中第-5-个内存地址---2090766940096
---列表中第-5-个字典---{'tt': [1, 2, 3]}
---list1---[{'tt': [1, 2, 3]}, {'tt': [1, 2, 3]}, {'tt': [1, 2, 3]}, {'tt': [1, 2, 3]}, {'tt': [1, 2, 3]}]
二、问题原因
1、字典用key-value来添加值时,如果每次的key相同,则相当于赋值,只是修改字典中该key所在的内存地址(引用)下的value,并不会在字典中添加新的key-value,所以for循环过程中,指向同一个内存地址(引用)的字典都会被修改。
2、列表添加方法append()添加值时,相当于只会添加一个该值的内存地址(引用),所以for循环过程中,列表中添加的值都会被修改。
三、解决方法
1、直接指向新字典对象(深拷贝)
(1)python代码
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:bigbear
# datetime:2022/9/8 20:29
# software: PyCharm
import copy
t = {"tt": "DUCLAE"}
print(f"---t初始内存地址---{id(t)}")
list0 = [1, "33", 5, {"gg": "sad"}, [1, 2, 3]]
list1 = []
for n in list0:
# 直接指向新字典对象,而不是赋值(深拷贝)
t = {"tt": n}
print(f"\t---t被赋值后内存地址---{id(t)}")
list1.append(t)
for i, n1 in enumerate(list1):
print(f"\t---列表中第-{i + 1}-个内存地址---{id(n1)}")
print(f"\t---列表中第-{i + 1}-个字典---{n1}")
print(f"\t---list1---{list1}\n")
(2)运行结果
---t初始内存地址---2250142758848
---t被赋值后内存地址---2250145875776
---列表中第-1-个内存地址---2250145875776
---列表中第-1-个字典---{'tt': 1}
---list1---[{'tt': 1}]---t被赋值后内存地址---2250145876224
---列表中第-1-个内存地址---2250145875776
---列表中第-1-个字典---{'tt': 1}
---列表中第-2-个内存地址---2250145876224
---列表中第-2-个字典---{'tt': '33'}
---list1---[{'tt': 1}, {'tt': '33'}]---t被赋值后内存地址---2250145911872
---列表中第-1-个内存地址---2250145875776
---列表中第-1-个字典---{'tt': 1}
---列表中第-2-个内存地址---2250145876224
---列表中第-2-个字典---{'tt': '33'}
---列表中第-3-个内存地址---2250145911872
---列表中第-3-个字典---{'tt': 5}
---list