2017-02-26 8 views
2

Ich möchte Gruppen basierend auf Wörterbuchschlüssel erstellen. Wenn der Schlüssel in mehr als einem Wörterbuch vorhanden ist, möchte ich eine Gruppe erstellen, die ich später verwenden kann. Ich bin fast gelungen, aber ich kann die gewünschte Leistung nicht erreichen. Wie Sie unten sehen können, gibt es zwei mögliche Gruppen. Das sind dct1 und dct3 (gleicher Schlüssel 18) und dct 2 und dct 4 (gleicher Schlüssel 8). Unten ist was ich bisher erstellt habe.Erstellen von Gruppen basierend auf dct.keys in Python

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

Wenn ein Schlüssel sagen 10 in allen dicts. Wie würde Ihre gewünschte Ausgabe aussehen? – kofrasa

+0

Überprüft für Sie. Es erstellt eine Liste innerhalb der Liste und dann in einer weiteren Liste. – Hsin

Antwort

1

Nachfolgend erzeugt die gewünschte Leistung, zumindest für das Beispiel, das Sie gab. Dies wird eine Gruppe für jeden Schlüssel erstellen, die in mehreren dicts auftritt:

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 ​​ist nicht definiert. Es ist auch möglich zu sagen, was in diesem Code passiert, ich kann es einfach kopieren, indem ich nicht viel von dem verstehe, was hier passiert. – Hsin

+0

Bitte sehen Sie sich meine Antwort an. ähnliche Inspiration zu diesem Beitrag und vielleicht ein bisschen lesbarer. – Crispin

+0

Oh lists_with_key.values ​​sollte durch key_groups ersetzt werden. Es bleibt ein Problem. Code erstellt keine Gruppe, wenn im Wörterbuch ein Schlüssel vorhanden ist. – 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) ] 

Ausgang:

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

Was passiert, wenn ein Schlüssel in 3 Diktaten auftritt? Sie werden drei Gruppen von zwei erstellen. – schwobaseggl

+0

code funktioniert nicht, wenn mehr als 4 dict vorhanden sind – 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

scheint Code nicht Gruppe für Schlüssel zu erstellen, die kein Paar haben (Beispiel dct5 = {99: [(40, 2)]}) – Hsin

+0

I Der Code wurde so geändert, dass er nicht verbundene Wörterbücher enthält. – Crispin

Verwandte Themen