字典中所有键之间的共同项

时间:2014-04-24 15:19:07

标签: python dictionary

我有一个“259136键”字典,每个键都有1个或多个值。

我的目标是“找到至少一个与键列表中的另一个键共有的值的键?”

我尝试过不同的方法来处理这个问题,但我一直在寻找更快的解决方案。我试过了

  1. 每个键与259135键进行比较以检查上述情况
  2. 将字典从键值反转为值键,所以现在值变为键,这样我将有两个字典,我可以转到第一个,并根据第一个中的值从中拉出所有值第二个。

1 个答案:

答案 0 :(得分:2)

使用集合词:

d={    'k1': [1,2,3],
       'k2': [2],
       'k3': [10],
       'k4': [3,2]
    }

com_keys={}
for k, v in d.items():
    for e in v:
        com_keys.setdefault(e, set()).add(k)    

print com_keys   
# {1: set(['k1']), 10: set(['k3']), 3: set(['k1', 'k4']), 2: set(['k2', 'k1', 'k4'])}

然后,如果你只想要那些共同拥有多个键的那个,那么只需要用dict理解过滤(或者对于旧的Pythons来说等):

>>> {k:v for k,v in com_keys.items() if len(v)>1 }
{2: set(['k2', 'k1', 'k4']), 3: set(['k1', 'k4'])}

如果你的dict是支持迭代(列表,元组等)与单个项目的集合的非同质组合,那么会更具挑战性。要么不支持迭代(整数,浮点数),要么你不想用for循环(字符串,unicode,其他字符串等)进行迭代

例如,假设您有一系列列表和单个项目'是整数和字符串:

import collections

d={    'k1': [1,2,3],
       'k2': 2,
       'k3': [10],
       'k4': [3,2],
       'k5': 'string',
       'k6': ['string',2]
    }

com_keys={}
for k, v in d.items():
    if not isinstance(v, basestring) and isinstance(v, collections.Iterable):   
        for e in v:
            com_keys.setdefault(e, set()).add(k)    
    else:        
        com_keys.setdefault(v, set()).add(k)

print com_keys
# {1: set(['k1']), 10: set(['k3']), 3: set(['k1', 'k4']), 2: set(['k2', 'k1', 'k6', 'k4']), 'string': set(['k6', 'k5'])}
print {k:v for k,v in com_keys.items() if len(v)>1 }   
# {2: set(['k2', 'k1', 'k6', 'k4']), 3: set(['k1', 'k4']), 'string': set(['k6', 'k5'])}