【问题标题】:Deleting items from a dictionary with a for loop [duplicate]使用for循环从字典中删除项目[重复]
【发布时间】:2014-06-28 22:56:14
【问题描述】:

如果键的值低于某个阈值,我会尝试从字典中删除项目。举一个简单的例子来说明我的意思:

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. 找出是否有不需要创建新字典(仅包含值 >= 阈值的键)的优雅解决方案。

  2. 在这里尝试理解 Python 的基本原理。我给自己读的方式是:“转到第一个键。该键的值是否

【问题讨论】:

    标签: python python-2.7 dictionary iteration


    【解决方案1】:

    由于 Python 字典是作为哈希表实现的,因此您不应依赖它们具有任何顺序。密钥顺序可能会发生不可预测的变化(但仅在插入或移除密钥之后)。因此,不可能预测下一个键。 Python 抛出 RuntimeError 是为了安全,并防止人们遇到意外的结果。

    Python 2 的 dict.items 方法返回键值对的副本,因此您可以安全地对其进行迭代并通过键删除不需要的值,正如 cmets 中建议的 @wim .示例:

    for k, v in my_dict.items():
        if v < threshold_value:
            del my_dict[k]
    

    但是,Python 3 的 dict.items 返回一个 view object,它反映了对字典所做的所有更改。这就是上述解决方案仅适用于 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。

    【讨论】:

      【解决方案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}
      

      【讨论】:

      • 正如我在 OP 中所说,我不想创建新的字典。
      • 您要求一种优雅的方式。但是你可以编程任何你喜欢的东西。
      【解决方案3】:

      我猜想在迭代集合的同时修改集合是一件很难正确实现的事情。考虑以下例子:

      >>> 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。这在字典中非常相似,删除/添加条目可能会使定义迭代顺序的内部结构无效(例如,您删除了足够多的条目,因此哈希映射桶大小发生了变化)。

      要解决您的问题 --- 只需创建新字典并在那里复制项目。至于

      【讨论】:

        猜你喜欢
        • 2019-03-14
        • 2018-02-16
        • 2016-03-13
        • 2013-04-19
        • 1970-01-01
        • 1970-01-01
        • 2011-03-09
        • 2023-01-25
        相关资源
        最近更新 更多