考虑以下代码
#! /usr/bin/env python
my_dict = {1:['Bernd','das','Brot'], 2:['Chili','das','Schaf'], 3:['Briegel','der','Busch']}
print my_dict
chili = my_dict[2]
print chili
del chili[2]
print chili
print my_dict
使用我的Python 2.7.5产生以下输出:
{1: ['Bernd', 'das', 'Brot'], 2: ['Chili', 'das', 'Schaf'], 3: ['Briegel', 'der', 'Busch']}
['Chili', 'das']
{1: ['Bernd', 'das', 'Brot'], 2: ['Chili', 'das'], 3: ['Briegel', 'der', 'Busch']}
正如您所看到的,dict中的列表也被操作,因此它们似乎指向内存中的相同对象/事物。
也许我理解这里错误的基本Python原则(随意指出火花并指向我的规范),但这是预期的行为吗?如果是的话,有没有办法从dict中删除和输入索引而不操纵原始字典?我常常发现已经有一种非常简单的Python方式来处理我尝试用复杂代码构造完成的东西。
我在这里有一个大字典,我经常从中取出列表,而且每次我以任何方式处理列表时都不想重建字典。
非常感谢你的时间和时间。帮助,
托拜厄斯
答案 0 :(得分:2)
是的,这是预期的行为。字典和列表中的Python名称和条目仅仅是实际对象的引用,存储在内存中的大堆(堆)中。
因此,my_dict[2]
和chili
都指向相同的list
对象,list
个对象是可变的。从list
对象中删除条目意味着对该对象的所有引用都会看到更改。
如果您希望chili
不是同一个列表对象,则必须创建副本。您可以使用以下任一项创建浅表副本:
chili = my_dict[2][:]
从第一个到最后一个索引的切片产生一个新的列表对象,或者使用:
chili = list(my_dict[2])
生成一个新的list
对象,复制存储在原始序列中的所有引用。
这些创建浅副本;如果my_dict[2]
中的任何内容本身都是可变的,那么您仍然会操纵chili
列表和my_dict[2]
列表之间共享的对象。
您可以使用copy.deepcopy()
function创建一个深层副本,它以递归方式生成对象的副本。
答案 1 :(得分:0)
当你写:
chili = my_dict[2]
然后chili
是与my_dict[2]
相同的对象的引用。因此,修改chili
会修改my_dict
。
您可以复制列表:
chili = list(my_dict[2])
现在del chili[2]
不会修改my_dict
。