【问题标题】:Behaviour of DEL with list taken from a dictDEL 的行为与从字典中获取的列表
【发布时间】:2014-02-04 11:03:34
【问题描述】:

考虑下面的代码

#! /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 原则(请随意抨击并将我指向规范),但这是预期的行为吗?如果是的话,有没有办法在不操纵原始字典的情况下从字典中删除和按索引输入?我经常发现已经有一种非常简单的 Python 方法可以完成我尝试使用复杂代码结构完成的工作。

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

非常感谢您的时间和帮助,

托比亚斯

【问题讨论】:

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

标签: python list dictionary del


【解决方案1】:

是的,这是预期的行为。字典和列表中的 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 创建深层副本,它会递归地生成对象的副本。

【讨论】:

    【解决方案2】:

    当你写作时:

     chili = my_dict[2]
    

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

    你可以复制一个列表:

      chili = list(my_dict[2])
    

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

    【讨论】:

      猜你喜欢
      • 2020-03-26
      • 1970-01-01
      • 2021-04-28
      • 1970-01-01
      • 2011-11-08
      • 1970-01-01
      • 2013-08-22
      相关资源
      最近更新 更多