Python DEL的行为,列表取自dict

Python DEL的行为,列表取自dict,python,list,dictionary,del,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 使用my Python 2.7.5生成以下输出: {1: ['Bernd',

考虑以下代码

#! /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
使用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']}
如您所见,dict中的列表也被操纵,因此它们似乎指向内存中的同一对象/事物

也许我在这里理解了一个基本的Python原则错误(请随意点出&让我看一下规范),但这是预期的行为吗?如果是的话,有没有一种方法可以在不操纵原始dict的情况下从dict的列表中删除并按索引输入?我经常发现,对于我试图用复杂的代码构造完成的工作,已经有了一种非常简单的Python方法

我这里有一个很大的dict,我经常从中提取列表,我不想每次以任何方式处理列表时都重新生成dict

非常感谢您的时间和帮助

托拜厄斯当你写作时:

 chili = my_dict[2]
然后
chili
是对与
my_dict[2]
相同对象的引用。因此,修改
chili
将修改
my_dict

您可以复制以下列表:

  chili = list(my_dict[2])

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

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

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

如果希望chili不是同一个列表对象,则必须创建副本。您可以使用以下任一方法创建浅层副本:

chili = my_dict[2][:]
从第一个索引到最后一个索引的切片生成新的列表对象,或使用:

chili = list(my_dict[2])
它生成一个新的
列表
对象,复制原始序列中存储的所有引用

这些都是肤浅的复制品;如果
my_dict[2]
中的任何内容本身是可变的,那么您仍将操作
chili
列表和
my_dict[2]
列表之间共享的对象


您可以使用创建深度副本,它会递归生成对象的副本。

是的,这是一种预期行为,要获取列表副本,请使用切片或
copy.deepcopy
。这里的误解是您实际上根本没有从dict中“获取”列表;你只是给它加了一个名字。