DEL的行为与从dict中获取的列表

时间:2014-02-04 11:03:35

标签: python list dictionary del

考虑以下代码

#! /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方式来处理我尝试用复杂代码构造完成的东西。

我在这里有一个大字典,我经常从中取出列表,而且每次我以任何方式处理列表时都不想重建字典。

非常感谢你的时间和时间。帮助,

托拜厄斯

2 个答案:

答案 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