1

consider the following code

#! /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

which produces the following output with my 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']}

As you can see, the list in the dict was also manipulated, so they appear to point to the same object/thing in memory.

Maybe I understand a basic Python principle wrong here (feel free to flame & point me towards the spec), but is this intended behaviour? And if it is, is there a way to delete and entry by index from a list taken from a dict without manipulating the original dict? Quite often I find out there is already an extraordinary simple Python way for doing stuff I try to accomplish with complicated code constructs.

I have a large dict here and I take lists out of it quite often, and I don't want to rebuild the dict each time I process the list in any way.

Thank you very much for your time & help,

Tobias

4

2 回答 2

2

是的,这是预期的行为。字典和列表中的 Python 名称和条目仅仅是对实际对象的引用,存储在内存中的一大堆(堆)中。

因此,my_dict[2]andchili都指向同一个list对象,并且list对象是可变的。从对象中删除条目list意味着对该对象的所有引用都会看到更改。

如果你想chili成为不同的列表对象,你必须创建一个副本。您可以使用以下任一方法创建浅拷贝:

chili = my_dict[2][:]

因为从第一个索引到最后一个索引切片会产生一个新的列表对象,或者使用:

chili = list(my_dict[2])

它生成一个新list对象,复制存储在原始序列中的所有引用。

这些创建拷贝;如果其中的任何my_dict[2]内容本身是可变的,那么您仍然会操作chili列表和my_dict[2]列表之间共享的对象。

copy.deepcopy()您可以使用函数创建深层副本,该函数递归地生成对象的副本。

于 2014-02-04T11:10:11.420 回答
0

当你写:

 chili = my_dict[2]

然后chili是对与 相同的对象的引用my_dict[2]。所以修改chili会修改my_dict.

您可以复制一个列表:

  chili = list(my_dict[2])

现在del chili[2]不会修改my_dict

于 2014-02-04T11:08:18.220 回答