Python中“字典在迭代期间改变大小”和“字典键在迭代期间改变”异常有什么区别

问题描述 投票:0回答:1

我正在准备一份有关 Python 中迭代器如何工作的材料,目前我正在研究如果更改正在迭代的字典会发生什么情况的部分内容。我知道并将其添加到我的材料中,这是不好的做法,但我仍然想尝试看看会发生什么。

下面的代码打印了键 5 并给了我一个“字典在迭代期间改变大小”异常。因此,当我有更改并想要转到下一个时,我就得到了例外。

d = {5:5, 10:10, 15:15, 20:20}
for elem in d:
    print(elem)
    d[elem+1] = elem+1

这样就可以了。但后来我想到,如果我同时执行添加和删除操作,以便技术上的大小不会改变,会怎么样?所以我写了这个:

d = {5:5, 10:10, 15:15, 20:20, 25:25, 30:30, 35:35}
for elem in d:
    print(elem)
    del d[elem]
    d[elem+1] = elem+1  

它打印与字典中的元素一样多的键(7),其中一些已经是新添加的值,但在打印 7 个值后,它会抛出“字典键在迭代过程中更改”异常。 现在我真的很好奇内部发生了什么,导致了这个。我仍然知道这是不好的做法,我只是想理解它。 谢谢!

python dictionary iterator
1个回答
0
投票

是的,这是一个相当“Pythonic”的事情:Python 的字典和迭代器并不是为动态处理更改而设计的,因此出现了您观察到的异常。

原因是因为当您迭代字典时,它会创建一个迭代器对象,该对象通过逐一遍历字典的键来跟踪迭代的状态。但是,如果在迭代时修改字典,Python 就无法保证迭代状态的完整性。这是因为修改字典可能会改变其内部结构,从而可能使当前迭代状态无效。

在第二个代码中,您从字典中删除当前的键 elem,并在每次迭代中添加新的键 elem+1,但是当您删除键时,它会改变字典的内部结构。即使您之后立即添加一个新键,Python 的迭代器也不能很好地处理这种情况,因为它不是为跟踪此类动态变化而设计的。

当Python在迭代过程中尝试获取下一个键时,发现字典的内部结构发生了变化,从而导致“字典键在迭代期间发生变化”异常。

© www.soinside.com 2019 - 2024. All rights reserved.