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

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

  2. 在这里尝试理解 Python 的基本原理。我自己读它的方式是:“转到第一个键。那个键的值 < x 吗?如果是 - 删除这个键:值项并继续字典中的下一个键,如果不是 - 继续什么都不做的下一个键”。换句话说,以前的 key 历史上发生的事情不应该影响我接下来的去向。无论过去如何,我都期待着下一个项目。 我知道这很有趣(有些人可能会说这很愚蠢,我会告诉你)但是 Python 对这个循环的“思考方式”是什么?为什么它不起作用? Python 将如何大声朗读它?只是想更好地理解语言......

最佳答案

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

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

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

然而,Python 3 的 dict.items 返回 view object反射(reflect)了对字典所做的所有更改。这就是上述解决方案仅适用于 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。

关于python - 使用 for 循环从字典中删除项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23594464/

相关文章:

尝试在远程桌面上运行应用程序时出现 Python 错误

python-2.7 - appcfg.py 在命令行中不工作

python-2.7 - ipython/pylab/matplotlib安装初始化报错

python - 如何比较字典并查看发生了什么变化?

python - 如何使用 ./从 Linux 终端运行 python?

python - 如何在 Pandas 数据框中保留前两个副本?

python - 根据内容过滤字符串列表

python - 在图像上滑动窗口 OpenCV

java - 按值中的多个字段对 Map 进行排序(Map 作为值)

c++ - 以 map 作为参数的函数不起作用