【问题标题】:Filter common sub-dictionary keys in a dictionary过滤字典中的常用子字典键
【发布时间】:2016-08-14 14:46:42
【问题描述】:

如何过滤父字典中其他子字典键中存在的所有公共子字典键

d = {
  '0': {'key_x': 0, 'key_y': 15, 'key_z': 41}
  '1': {'key_x': 5, 'key_y': 22}
  '2': {'key_x': 6, 'key_y': 41}
}

result ['key_x', 'key_y']

目前的解决方案是

intersect = {}
for k in corner_values.keys():
    for j in corner_values[k]:
        if j not in intersect:
            intersect[j] = 1
        else:
            intersect[j] += 1

for k in intersect:
    if intersect[k] != len(corner_values.keys()):
        del intersect[k]

有没有更简单的解决方案?

【问题讨论】:

    标签: python dictionary filter


    【解决方案1】:

    您可以将字典mapset,然后使用set.intersectionreduce

    >>> from functools import reduce # if you are using Python 3
    >>> d = {                       
    ...   '0': {'key_x': 0, 'key_y': 15, 'key_z': 41},
    ...   '1': {'key_x': 5, 'key_y': 22},
    ...   '2': {'key_x': 6, 'key_y': 41}
    ... }
    >>> reduce(set.intersection, map(set, d.values()))
    {'key_x', 'key_y'}
    

    注意:在 Python 3 中,reduce 已移至 functools

    更新:正如@John 的answer 中所见,set.intersection 可以处理任意数量的集合,因此reduce 甚至没有必要。就set.intersection(*map(set, d.values()))

    【讨论】:

      【解决方案2】:

      提取所有密钥后,您可以执行单个 set.intersection 操作。那么它是单行的:

      set.intersection(*(set(x) for x in d.itervalues()))
      

      分解后,评估的第一部分是这样的:

      (set(x) for x in d.itervalues())
      

      这是一个生成器,它产生:

      {'key_x', 'key_y'}, {'key_x', 'key_y', 'key_z'}, {'key_x', 'key_y'}
      

      在 Python 3 中,该生成器相当于:

      map(set, d.values())
      

      但在 Python 2 中,map 的效率较低,因为它构造了一个我们不需要的 list(就像 values() 而不是 itervalues())。

      在任何情况下,该生成器的结果都会传递给set.intersection(使用* 参数解包器),以便在一次调用中完成繁重的工作。

      【讨论】:

      • 不错。不知道intersection 工作过“可变参数”风格。
      • Python 2 有itertools.imap
      • 此外,即使您使用生成器,当您使用 * 调用带有它的函数时,其元素仍将存储在用于参数的容器中 (*args)。尽管如此,消除中介list 是一件好事。
      【解决方案3】:

      pandas 的替代方案,无需订购按键:

      import pandas as pd
      
      list(pd.DataFrame(d).dropna().index)
      
      #['key_x', 'key_y']
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-27
        • 1970-01-01
        • 2013-07-01
        • 1970-01-01
        相关资源
        最近更新 更多