我在 python 中有一个字典,看起来像这样
my_dict = {
'100':[['a', [10], [5]]],
'101':[['a', [10], [7]]],
'102':[['a', [10], [11]]],
'103':[['a', [10], [4]]],
}
要创建 my_dict,
my_dict = dict()
id_nums = ['100', '101', '102', '103', ...]
for id in id_nums:
info_list = list()
## code to populate info list
# based on certain conditions
if some_condition:
info_list.insert(0, 'a')
info_list.insert(1, list1) # list_1 is passsed from another function
else:
info_list.insert(0, 'a')
info_list.insert(1, [])
if other_condition:
info_list.insert(2, list2) # list2 is being passed from other function
else:
info_list.insert(2, [])
if id not in my_dict.keys():
my_dict[id] = list()
my_dict[id].append(info_list)
其中信息列表包含 ['a', [10], [x]。
我正在循环遍历中的所有键dict ,我的目标是删除每个值中第一个索引处的数字,即 10。为了实现这一点,我有:
for k in my_dict.keys():
my_dict[k][1].remove(10)
当我执行上面的代码时,在第一个键(即“100”)处,删除方法也会从值中删除 10 my_dict 中的所有键。
任何人都可以帮助我理解为什么会发生这种情况吗?以及如何避免?
谢谢
发生这种情况的原因是,你所有的字典值都指向了
相同的
列表
[10]
在内存中。为了理解这一点,让我们分解一下你的代码:
-
创建列表: 当你运行
info_list.insert(1, list1)
时,你并没有创建一个新的列表[10]
。相反,你在info_list
中插入了list1
的一个 引用 。如果list1
在不同的迭代中没有改变,那么所有的info_list
都会在索引1
处包含对同一个列表对象的引用。 -
修改列表: 当你执行
my_dict[k][0][1].remove(10)
时,你正在修改这个共享列表对象。由于所有键都指向这个列表,所以更改在所有地方都可见。
如何避免这种情况:
你需要确保每个字典值都有自己的独立列表。你可以通过在每次迭代中创建一个新的列表来实现这一点:
for id in id_nums:
info_list = list()
# ... your code to populate info_list ...
# 创建一个新的列表,而不是插入 list1
if some_condition:
info_list.insert(0, 'a')
info_list.insert(1, list1.copy()) # 创建 list1 的副本
else:
# ...
# 对 list2 也做同样的事情
# ... 你的剩余代码 ...
通过使用
list1.copy()
,你创建了一个新的列表,其中包含
list1
中的相同元素。现在,对这个新列表的修改不会影响其他字典值。
另一种方法
是直接在
info_list
中创建列表,而不是插入外部列表:
if some_condition:
info_list.insert(0, 'a')
info_list.insert(1, [10]) # 直接创建一个新的 [10] 列表
else:
# ...
选择哪种方法取决于你的具体情况和
list1
和
list2
是如何生成的。