如果密钥的值低于某个阈值,我试图从字典中删除项目。我的意思是一个简单的例子:
my_dict = {'blue': 1, 'red': 2, 'yellow': 3, 'green': 4}
for color in my_dict:
threshold_value = 3
if my_dict[color] < threshold_value:
del my_dict[color]
print(my_dict)
现在,我收到RuntimeError: dictionary changed size during iteration
错误。没有什么大惊喜。我发布此问题的原因是:
找出是否有一个优雅的解决方案,不需要创建一个新词典(仅包含值> gt = =阈值的键)。
尝试理解Python的基本原理。我自己读的方式是:&#34;转到第一个键。该键的值是否为&lt; X ?如果是 - del这个键:值项并继续在字典中的下一个键,如果没有 - 继续到下一个键而不做任何事情&#34;。换句话说,历史上发生在以前的键上的事情不应该影响我下一步的去向。无论过去如何,我都期待着接下来的项目。 我知道这很有趣(有些人可能会说愚蠢,我会给你这个)但是Python的思维方式是什么&#34;关于这个循环?为什么它不起作用? Python如何大声读出它?只是想更好地理解语言......
答案 0 :(得分:10)
由于Python字典是作为哈希表实现的,因此您不应该依赖它们具有任何类型的顺序。密钥顺序可能无法预测地改变(但仅在插入或移除密钥之后)。因此,无法预测下一个关键。 Python会使RuntimeError
保持安全,并防止人们遇到意外结果。
Python 2的dict.items
方法返回键值对的副本,因此您可以安全地迭代它并删除键不需要的值,如{{3} }在评论中建议。例如:
for k, v in my_dict.items():
if v < threshold_value:
del my_dict[k]
然而,Python 3的dict.items
返回@wim,反映了对字典所做的所有更改。这就是上述解决方案仅适用于Python 2的原因。您可以将my_dict.items()
转换为list
(tuple
等)以使其与Python 3兼容。
解决问题的另一种方法是选择要删除的密钥,然后删除它们
keys = [k for k, v in my_dict.items() if v < threshold_value]
for x in keys:
del my_dict[x]
这适用于Python 2和Python 3。
答案 1 :(得分:2)
字典无序。通过删除一个密钥没人能说,下一个密钥是什么。所以python一般不允许在字典中添加或删除键,而不是迭代。
只需创建一个新的:
my_dict = {"blue":1,"red":2,"yellow":3,"green":4}
new_dict = {k:v for k,v in my_dict.iteritems() if v >= threshold_value}
答案 2 :(得分:0)
我想在迭代它时修改一个集合是一件很难实现的事情。请考虑以下问题:
>>> list = [1, 2, 3, 4, 5, 6]
>>> for ii in range(len(list)):
print list[ii];
if list[ii] == 3:
del list[ii]
1
2
3
5
6
请注意,在此示例中,完全省略了4。它在字典中非常相似,删除/添加条目可能会使定义迭代顺序的内部结构无效(例如,您删除了足够的条目,因此哈希映射存储桶大小已更改)。
要解决您的情况---只需创建新词典并在那里复制项目。至于