使用for循环从字典中删除项目

时间:2014-05-11 15:27:49

标签: python python-2.7 dictionary iteration

如果密钥的值低于某个阈值,我试图从字典中删除项目。我的意思是一个简单的例子:

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错误。没有什么大惊喜。我发布此问题的原因是:

  1. 找出是否有一个优雅的解决方案,不需要创建一个新词典(仅包含值> gt = =阈值的键)。

  2. 尝试理解Python的基本原理。我自己读的方式是:&#34;转到第一个键。该键的值是否为&lt; X ?如果是 - del这个键:值项并继续在字典中的下一个键,如果没有 - 继续到下一个键而不做任何事情&#34;。换句话说,历史上发生在以前的键上的事情不应该影响我下一步的去向。无论过去如何,我都期待着接下来的项目。 我知道这很有趣(有些人可能会说愚蠢,我会给你这个)但是Python的思维方式是什么&#34;关于这个循环?为什么它不起作用? Python如何大声读出它?只是想更好地理解语言......

3 个答案:

答案 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()转换为listtuple等)以使其与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。它在字典中非常相似,删除/添加条目可能会使定义迭代顺序的内部结构无效(例如,您删除了足够的条目,因此哈希映射存储桶大小已更改)。

要解决您的情况---只需创建新词典并在那里复制项目。至于

相关问题