为什么python词典会对在另一个平等字典上执行的操作做出反应?

时间:2016-03-28 12:41:15

标签: python dictionary

对于混淆标题名称感到抱歉,我不太清楚如何说出来。 我有以下代码:

eps = []
newdict = dictionary.items
for ep in range(minepisode, maxepisode + 1):
    eps.append(str(ep))
for key in dictionary.keys():
    if key not in eps:
        newdict.pop(key)

但是,当我尝试运行它时,它会返回错误

RuntimeError: dictionary changed size during iteration

尽管正在对“新闻”进行修改。而不是'字典',这是我正在迭代的那个。

在shell中乱搞之后,我发现如果我制作了两个相同的字典:

x = {'1':'something'}
newx = x
newx.pop('1')

' 1'键入x和newx被删除。为什么是这样?我该如何修复原始代码中的错误?

4 个答案:

答案 0 :(得分:2)

首先,python中的dictmutable数据结构..

所以,它就像这样......

x = {'1':'something'}

所以,这里创建了dict对象x ......

newx = x

所以,在这里,您将同一个dict对象引用到名为variable的另一个newx

理想情况下,您没有创建新对象,只是将同一对象引用到其他变量..

你可以看到这样的相似性..

>>> id(x)
140222539383424
>>> id(newx)
140222539383424

两个对象的ID都相同......

您还可以使用object similarity

进行is检查来验证这一点
>>> newx is x
True

因此,出于显而易见的原因,无论您是要更改x还是newx,都要更改相同的引用对象。

答案 1 :(得分:0)

如果你想在循环中改变一个字典,你应该使用copy.deepcopy();它将为两者分配单独的内存。

示例:

import copy

a = {'key':'value'}
b = copy.deepcody(a)

希望它会对你有所帮助。 :)

答案 2 :(得分:0)

你有一只狗,你是一个非凡的人,你甚至可以在几天内给你的狗flash打电话,在奇数的时候打turtle。今天,3月28日flash伤了他们的右前腿,如果明天你发现turtle右前腿受伤了,你会感到惊讶吗?

Python就是这样,你有永久的对象和你坚持的名字...其中一些对象是不可变的(例如,字符串)当你想要修改其中一个他们正在创建一个新对象,旧对象仍在,旧标记为flash,新标记为turtle ---其他是可变(例如,字典)以便可以直接将更改应用于对象本身,这仍然由所有名称引用。

对我来说,不可变的对象的行为是最令人惊讶的,但我知道我是少数......因此我需要保护。

免责声明:在制作这篇文章时,没有动物受伤。

答案 3 :(得分:0)

考虑您有一个列表colours=['blue','green]。当您执行palette=colours之类的操作时,您将palette设为colours的别名:它们都指向位于相同内存地址的相同列表。

colours=['blue','green']
palette=colours
print id(colours)==id(palette) #True
print id(colours[0])==id(palette[0]) #True

有一种方法可以改变它。考虑定义palette=list(colours)。现在,您创建了一个位于内存中另一个地址的新列表。但现在两个列表都包含同一地址的元素:palette [0]和colors [0]位于同一地址。

colours=['blue','green']
palette=list(colours)
print id(colours)==id(palette) #False
print id(colours[0])==id(palette[0]) #True

最后,你有深度复制

from copy inport deepcopy
colours=['blue','green']
palette=deepcopy(colours)
print id(colours)==id(palette) #False
print id(colours[0])==id(palette[0]) #False