反转多组字典

时间:2016-12-11 22:41:56

标签: python python-3.x dictionary set

假设我有一套集:

DictofSets={
    'Key1':set(['A', 'B', 'D', 'F']),
    'Key2':set(['B', 'C', 'G']),
    'Key3':set(['A', 'B', 'D', 'F']),
    'Key4':set(['A', 'B', 'C', 'D', 'F']),
    'Key5':set(['A', 'B', 'E', 'F'])}

现在假设我想在多个集合中的集合中找到集合元素的键。

我能做的最好的事情就是:

from collections import Counter

# first get counts of elements in excess of 1:
c=Counter()
for s in DictofSets.values():
    c+=Counter(s)

# dict of lists for the keys if the set item occurs more than once
inverted={k:[] for k, v in c.items() if v>1} 
for k in sorted(DictofSets):
    for e in DictofSets[k]:
        if e in inverted:
            inverted[e].append(k)

它产生我想要的东西:

>>> inverted
{'A': ['Key1', 'Key3', 'Key4', 'Key5'], 
 'C': ['Key2', 'Key4'], 
 'B': ['Key1', 'Key2', 'Key3', 'Key4', 'Key5'], 
 'D': ['Key1', 'Key3', 'Key4'], 
 'F': ['Key1', 'Key3', 'Key4', 'Key5']}

但它看起来有点笨拙。有更简单的方法吗?

2 个答案:

答案 0 :(得分:2)

我认为OP方法没有任何问题。它可以更简洁地表达,但这并没有使这更好:

>>> import itertools as it
>>> c = Counter(it.chain.from_iterable(DictofSets.values()))
>>> {l: {k for k, s in DictofSets.items() if l in s} for l, n in c.items() if n > 1}
{'A': {'Key1', 'Key3', 'Key4', 'Key5'},
 'B': {'Key1', 'Key2', 'Key3', 'Key4', 'Key5'},
 'C': {'Key2', 'Key4'},
 'D': {'Key1', 'Key3', 'Key4'},
 'F': {'Key1', 'Key3', 'Key4', 'Key5'}}

答案 1 :(得分:0)

这是defaultdict的工作

>>> DictofSets={
    'Key1':set(['A', 'B', 'D', 'F']),
    'Key2':set(['B', 'C', 'G']),
    'Key3':set(['A', 'B', 'D', 'F']),
    'Key4':set(['A', 'B', 'C', 'D', 'F']),
    'Key5':set(['A', 'B', 'E', 'F'])}
>>> from collections import defaultdict
>>> SetsofDicts = defaultdict(set)
>>> for key, values in DictofSets.items():
        for x in values:
            SetsofDicts[x].add(key)


>>> from pprint import pprint
>>> pprint(SetsofDicts)
defaultdict(<class 'set'>,
            {'A': {'Key3', 'Key1', 'Key5', 'Key4'},
             'B': {'Key3', 'Key1', 'Key5', 'Key2', 'Key4'},
             'C': {'Key4', 'Key2'},
             'D': {'Key3', 'Key1', 'Key4'},
             'E': {'Key5'},
             'F': {'Key3', 'Key1', 'Key5', 'Key4'},
             'G': {'Key2'}})
>>> 

一旦你得到它,删除不需要的条目很容易,并且有很多方法可以做到这一点,例如

>>> for toremove in [ k for k,v in SetsofDicts.items() if len(v)<=1 ]:
        del SetsofDicts[toremove]


>>> pprint(SetsofDicts)
defaultdict(<class 'set'>,
            {'A': {'Key3', 'Key1', 'Key5', 'Key4'},
             'B': {'Key3', 'Key1', 'Key5', 'Key2', 'Key4'},
             'C': {'Key4', 'Key2'},
             'D': {'Key3', 'Key1', 'Key4'},
             'F': {'Key3', 'Key1', 'Key5', 'Key4'}})
>>>