2017-02-26 14 views
2

辞書キーに基づいてグループを作成したいと思います。キーが複数の辞書にある場合は、後で使用できるグループを作成したいと思う。私はほとんどsuccededしかし、私は希望の出力を得ることができません。以下に示すように、2つの可能なグループがあります。これはdct1とdct3(同じキー18)とdct2とdct4(同じキー8)です。以下は私がこれまでに作ったものです。Pythonでdct.keysに基づいてグループを作成する方法

dct1 = {20: [(87, 6), (87, 7)], 
     21: [(68, 8)], 
     18: [(30, 7)], 
     11: [(27, 7), (28, 7)]} 

dct2 = {8: [(41, 5), (41, 6), (41, 4)], 
     14: [(4, 7), (5, 7), (6, 7)], 
     16: [(58, 7), (56, 7), (57, 7)]} 

dct3 = {4: [(41, 5), (41, 6), (41, 4)], 
     15: [(77, 7), (78, 7)], 
     18: [(29, 9), (29, 8)], 
     3: [(27, 7), (28, 7)]} 

dct4 = {8: [(41, 5), (41, 6), (41, 4)], 
     30: [(6, 9), (5, 7), (7, 9)], 
     35: [(58, 7), (56, 7), (57, 7)]} 

rwawl = [dct1, dct2, dct3, dct4] 


def group_rooms(rectangles_with_adjacent_walls_list): 
    groups = [] 
    for rectangle in rectangles_with_adjacent_walls_list: 
     adjacent_wall_list = rectangle.keys() 
     if not groups: 
      groups.append([adjacent_wall_list]) 
     print adjacent_wall_list 
     new_group_threshold = len(adjacent_wall_list) 
     new_group = 0 

     for adjacent_wall in adjacent_wall_list: 
      for added_room in groups: 
       if adjacent_wall in added_room: 
        added_room.append(adjacent_wall_list) 
        break 
       else: 
        new_group += 1 

      if new_group == new_group_threshold: 
       groups.append([adjacent_wall_list]) 

    print groups 
    return groups 


created_groups = group_rooms(rwawl) 

# MY OUTPUT: 
# [[[18, 11, 20, 21]], [[18, 11, 20, 21]], [[18, 3, 4, 15]], [[8, 35, 30]]] 

# DESIRED OUTPUT: 
# [[[18, 11, 20, 21], [18, 3, 4, 15]], [[8, 16, 14], [8, 35, 30]]] 
+0

:これはのために、複数のdictsに発生するすべてのキーをグループを作成します。あなたの望む出力はどのように見えますか? – kofrasa

+0

あなたのためにそれをチェックしました。それはリストの中に1つのリストを作成し、もう1つのリストに作成します。 – Hsin

答えて

1

以下は、少なくともあなたが与えたたとえば、あなたの所望の出力を生成します。キーがある場合は、すべてのdictsで10を言う

def group_rooms(dicts): 
    key_sets = [set(d.keys()) for d in dicts] 
    # union of all keys 
    total_keys = reduce(lambda x, y: x | y, key_sets, set()) 
    key_groups = [map(list, filter(lambda s: k in s, key_sets)) for k in total_keys] 
    # return groups with removed singletons 
    return filter(lambda s: len(s) > 1, key_groups) 
+0

lists_with_key.valuesが4つ以上存在しない場合、コードは機能しません。また、このコードで何が起きているのかを言うことは可能ですが、ここで何が起きるのか分かりません。 – Hsin

+0

私の答えを見てください。このポストに似たインスピレーションとおそらくもう少し読みやすい。 – Crispin

+0

Oh lists_with_key.valuesをkey_groupsに置き換える必要があります。 1つの問題が残っています。辞書に1つのキーがある場合、コードはグループを作成しません。 – Hsin

2
from itertools import combinations 
a = [dct1, dct2, dct3, dct4] 
b = [i.keys() for i in a] 
print [[i,j] for i,j in combinations(b,2) if set(i) & set(j) ] 

出力:

[[[18, 11, 20, 21], [18, 3, 4, 15]], [[8, 16, 14], [8, 35, 30]]] 
+0

3つの辞書にキーがある場合はどうなりますか? 2つの3つのグループを作成します。 – schwobaseggl

+0

dict – Hsin

1
from collections import defaultdict 
import itertools 

dct1 = {20: [(87, 6), (87, 7)], 
     21: [(68, 8)], 
     18: [(30, 7)], 
     11: [(27, 7), (28, 7)]} 

dct2 = {8: [(41, 5), (41, 6), (41, 4)], 
     14: [(4, 7), (5, 7), (6, 7)], 
     16: [(58, 7), (56, 7), (57, 7)]} 

dct3 = {4: [(41, 5), (41, 6), (41, 4)], 
     15: [(77, 7), (78, 7)], 
     18: [(29, 9), (29, 8)], 
     20: [(27, 7), (28, 7)]} 

dct4 = {8: [(41, 5), (41, 6), (41, 4)], 
     30: [(6, 9), (5, 7), (7, 9)], 
     35: [(58, 7), (56, 7), (57, 7)]} 

dct5 = {99: [(1, 1)]} 

l = [dct1, dct2, dct3, dct4, dct5] 

key_map = defaultdict(list) 
all_keys = set() 
for d in l: 
    all_keys.add(tuple(d.keys())) 
    for k in d.keys(): 
     key_map[k].append(tuple(d.keys())) 
dup_keys = [tuple(v) for k, v in key_map.items() if len(v) > 1] 
unique_dup_keys = set(itertools.chain(*dup_keys)) 
diff = all_keys - unique_dup_keys 

dup_keys = set(dup_keys) 

key_groups = list((dup_keys | diff)) 
print(key_groups) 

# [((8, 16, 14), (8, 35, 30)), (99,), ((18, 11, 20, 21), (20, 18, 4, 15))] 
+0

コードがペアを持たないキーのグループを作成しないようです(例:dct5 = {99:[(40,2)}) – Hsin

+0

対になっていない辞書を含むようにコードを修正しました。 – Crispin

関連する問題