迭代错误期间字典大小的变化

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

我正在编写代码以通过选择来删除字典中的某些项目,甚至使用字典的副本来防止在迭代过程中更改其大小,但是我一直收到此错误:

''RuntimeError:字典在迭代过程中更改了大小'

import copy
word = {'a':{'aa':{'aaa', 'aab'}, \
             'ab':{'aaa', 'aab'}}, \
        'b':{'ba':{'aaa', 'aab'}, \
             'bb':{'aaa', 'aab'}}, \
        'c':{'ca':{'aaa', 'aab'}, \
             'cb':{'aaa', 'aab'}}}
wordCopy = copy.copy(word)
for item in word.keys():
    for k in word[item].keys():
        print(k)
        print('Enter del to delete this item:')
        deleteCertificate = input()
        if deleteCertificate == 'del':
            del wordCopy[item][k]
word = wordCopy
print(word)
python-3.x dictionary iteration deep-copy shallow-copy
2个回答
1
投票
这是由于您的copy。实际上,它只是一个shallow copy。从文档:

浅表副本会构造一个新的复合对象,然后(在可能的范围内)将对原始对象的引用插入其中。

因此,当您浅表复制字典时,它仍然具有对原始字典的引用。您将看到此消息,如果在发生错误后打印出word,则会注意到已从其中删除了一个元素。

相反,您需要deep copy。再次从文档:

深层副本会构造一个新的复合对象,然后递归地将原始对象中的对象的副本插入其中。

如果替换行,可以避免出现错误:

wordCopy = copy.copy(word)

with:

wordCopy = copy.deepcopy(word)

我也建议您完整阅读docs on copy


0
投票
您的wordCopyword是分开的,但是wordCopy[item]word[item]是同一对象,因为copy.copy是浅表副本。

您可以进行深层复制,也可以只创建一个新的空对象,然后在颠倒的条件下插入需要保留的项目,而无需完全修改原始的word

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