【问题标题】:Remove entries of a dictionary that are not in a set删除不在集合中的字典条目
【发布时间】:2020-09-24 21:23:49
【问题描述】:

给定以下字典并设置:

d = {1 : a, 2 : b, 3 : c, 4 : d, 5 : e }
s = set([1, 4])

我想知道是否可以删除集合中未包含的所有字典条目(即 2、3、5)。 我知道我可以通过遍历字典并检查每个键来实现这一点,但是由于我是 Python 新手并且到目前为止遇到了许多“快捷方式”,我想知道是否存在针对这个特定问题的一个。

【问题讨论】:

    标签: python python-2.7


    【解决方案1】:
    d = {1 : 'a', 2 : 'b', 3 : 'c', 4 : 'd', 5 : 'e' }
    s = set([1, 4])
    

    由于您不应该在迭代字典时对其进行修改,因此您有两种可能来创建新字典。

    一种是从旧的过滤值中创建一个新的字典:

    d2 = dict((k,v) for k,v in d.iteritems() if k in s)
    

    第二个是提取键,将它们与s-set 相交并使用它们构建一个新字典:

    d2 = dict((k, d[k]) for k in set(d) & s)
    

    第三种是直接从d中移除元素:

    for k in set(d) - s:
        del d[k]
    

    【讨论】:

    • 呼,Python 令人困惑。为什么在迭代字典时修改字典不好?
    • 在迭代任何语言时修改任何容器都是不好的。这是因为迭代器可能会混淆。一般来说,迭代器期望容器的内部状态保持现在的状态,以便能够找出“下一个”元素在哪里。例如,当你迭代一个序列时,迭代器可能基于一个索引......如果你删除了接下来要出现的元素,然后索引盲目地增加,你实际上跳过了一个元素,并且可能结束超出范围。
    【解决方案2】:

    这里有两个不错的解决方案:

    d = {1 : "a", 2 : "b", 3 : "c", 4 : "d", 5 : "e" }
    keep_keys = set((1, 4))
    
    # option 1, builds a new dictionary
    d2 = {key:d[key] for key in set(d) & keep_keys}
    
    # option 2, modifies the original dictionary
    map(d.__delitem__, frozenset(d) - keep_keys)
    

    如果您想要的是速度,您应该分析两者中哪一个更快。

    【讨论】:

    • 如果 remove 中而不是 d 中的内容将引发 KeyError
    【解决方案3】:

    另一种解决方案:

    d = {1 : "a", 2 : "b", 3 : "c", 4 : "d", 5 : "e" }
    s = set([1, 4])
    r = { k:d[k] for k in ( d.viewkeys() - s ) }
    

    【讨论】:

      猜你喜欢
      • 2013-12-23
      • 2011-05-17
      • 1970-01-01
      • 2016-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多