2011-05-31 215 views
0
d = {'g1':{'p1':1,'p2':5,'p3':11,'p4':1}, 
    'g2':{'p1':7,'p3':1,'p4':2,'p5':8,'p9':11}, 
    'g3':{'p7':7,'p8':7}, 
    'g4':{'p8':9,'p9':1,'p10':7,'p11':8,'p12':3}, 
    'g5':{'p1':4,'p13':1}, 
    'g6':{'p1':4,'p3':1,'p6':2,'p13':1} 
    } 

對於一個給定字典「D」我想返回共享子辭典的至少兩個(「N」)鍵的簇(存在於所有給定羣集的子字典)。我們不在乎這些子詞典的價值。換句話說,給定集羣中所有子詞典的鍵的交集長度應至少爲2(或'n')。字典的字典:打印詞典共享至少兩個公共密鑰

+2

作業?你有什麼嘗試? – unholysampler 2011-05-31 21:04:14

+0

不是作業;)我現在如何在for循環中爲key對做這件事,但卻不知道如何在全局範圍內做到這一點 - 全是反對所有。 – 2011-05-31 21:14:33

回答

0

喜歡的東西

for keya in d: 
    tempd = {} 
    keys = set() 
    tempset = set(d[keya].keys()) 

    for keyb in d: 
     tempset &= d[keyb].keys() 

     if len(tempset) >= 2: 
      keys.add(keyb) 

    print({key: d[key] for key in keys}) 

可能會奏效。

編輯:不,它不工作。我需要考慮這個。

0

我覺得你應該先「倒置」的字典,然後找到解決辦法很簡單:

import collections 
inverted = collections.defaultdict(list) 

for key, items in d.items(): 
    for sub_key in items: 
     inverted[sub_key].append(key) 

for sub_key, keys in inverted.items(): 
    if len(keys) >= 2: 
     print sub_key, keys 
2

我希望我的理解正確,你想要什麼。這種方法笨拙,我擔心它效率很低。

我添加了一個字典G6至d以產生一個更有趣的輸出:

#! /usr/bin/env python 
# -*- coding: utf-8 -*- 

d = {'g1':{'p1':1,'p2':5,'p3':11,'p4':1}, 
    'g2':{'p1':7,'p3':1,'p4':2,'p5':8,'p9':11}, 
    'g3':{'p7':7,'p8':7}, 
    'g4':{'p8':9,'p9':1,'p10':7,'p11':8,'p12':3}, 
    'g5':{'p1':4,'p13':1}, 
    'g6':{'p1':1,'p9':2,'p11':12} 
    } 

clusters = {} 

for key, value in d.items(): 
    cluster = frozenset (value.keys()) 
    if cluster not in clusters: clusters [cluster] = set() 
    clusters [cluster].add (key) 


for a in clusters.keys(): 
    for b in clusters.keys(): 
     if len (a & b) > 1 and a^b: 
      cluster = frozenset (a & b) 
      if cluster not in clusters: clusters [cluster] = set() 
      for x in clusters [a]: clusters [cluster].add (x) 
      for x in clusters [b]: clusters [cluster].add (x) 

print "Primitive clusters" 
for key, value in filter (lambda (x, y): len (y) == 1, clusters.items()): 
    print "The dictionary %s has the keys %s" % (value.pop(), ", ".join (key)) 

print "---------------------" 
print "Non-primitive clusters:" 
for key, value in filter (lambda (x, y): len (y) > 1, clusters.items()): 
    print "The dictionaries %s share the keys %s" % (", ".join (value), ", ".join (key)) 
0

如果簡化問題,以長度爲2的唯一簇(即,對字典的)變得略微更清晰:從給定的迭代生成固定長度的子序列是完全相同的itertools.combinations作業:

>>> list(itertools.combinations(d, 2)) 
[('g5', 'g4'), ('g5', 'g3'), ('g5', 'g2'), ('g5', 'g1'), ('g4', 'g3'), ('g4', 'g 
2'), ('g4', 'g1'), ('g3', 'g2'), ('g3', 'g1'), ('g2', 'g1')] 

我們可以通過實現該視圖運行起來也()的行爲類似於看到任何字典的共同點的密鑰的數目設置(在Python 3中;在Python 2中,它可能是一個li ST):

>>> d['g1'].keys() & d['g2'].keys() 
{'p3', 'p1', 'p4'} 

&是交集操作 - 它爲我們提供了一組這些集合有共同的所有物品。因此,我們可以檢查是否有ATLEAST其中兩個通過檢查這一套,這讓我們的長度:

>>> common_pairs = [[x,y] for x,y in itertools.combinations(d, 2) 
            if len(d[x].keys() & d[y].keys()) >= 2] 
>>> common_pairs 
[['g2', 'g1']] 

求解未知的簇大小是有點困難 - 我們不能直接使用,如果在&操作我們並沒有對此進行硬編碼。值得慶幸的是,set類爲我們提供了一種以set.intersection的形式進行交集的方法。它不會接受dict_keys實例,但你可以很容易地解決這個問題通過調用設置:

>>> set.intersection(d['g1'].keys(), d['g2'].keys(), d['g5'].keys()) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: descriptor 'intersection' requires a 'set' object but received a 'dict_keys' 
>>> set.intersection(set(d['g1']), set(d['g1']), set(d['g5'])) 
{'p1'} 

您應該能夠通過ň相當平凡概括這個大小2的聚集。