2014-04-09 14 views
5

Jeśli mam słownika, co następuje:nowy słownik z wspólnej podklucz

{ 
    'key1': 
     { 
      'foo': 1233, 
      'bar': 1234, 
      'baz': 122 
     }, 
    'key2': 
     { 
      'foo': 113, 
      'bar': 333 
     } 
} 

jak mogę zwrócić nowy słownik z następującym wynikiem

{ 
    'key1': 
     { 
      'foo': 1233, 
      'bar': 1234 
     }, 
    'key2': 
     { 
      'foo': 113, 
      'bar': 333 
     } 
} 

chcę podrzędne słowniki (jest to prawo termin) z „” i „key1 Klawisz2” mają takie same klucze

+0

Innymi słowy: chcesz kropla * * wszystkie elementy, które nie znajdują się w obu słownikach? –

+0

Tak, wiem, że mogę to zrobić w php z liczbą wywołań array_ * z niektórymi anonimowymi funkcjami, ale czuję się ograniczający, kiedy przełączam się na pythona:/ – Jeffrey04

+0

Aktualizacja: wysłałem moją złowrogą złą odpowiedź na ten problem (python pro please don 't slap me) – Jeffrey04

Odpowiedz

4

ten powinien zrobić:

>>> d = { 'key1': { 'foo': 1233, 'bar': 1234, 'baz': 122 }, 'key2': { 'foo': 113, 'bar': 333 } } 
>>> keys = (x.keys() for x in d.itervalues()) 
>>> common_keys = set(next(keys)).intersection(*keys) 
>>> {k : {k_: v[k_] for k_ in common_keys} for k, v in d.iteritems()} 

{'key2': {'foo': 113, 'bar': 333}, 
'key1': {'foo': 1233, 'bar': 1234}} 
1

Inna odpowiedź:

def func(a): 
    res = {} 
    keys = a.keys() 
    common = reduce(lambda x, y: x & y, [set(a[i].keys()) for i in keys]) 
    for k in keys: 
     temp = {} 
     for c in common: 
      temp[c] = a[k][c] 

     res[k] = temp 

    return res 
+0

chciałem wypróbować bardziej funkcjonalny styl (unikanie zadania tak dużo jak to możliwe), wygląda na to, że twoje jest trochę bliższe temu, co chcę – Jeffrey04

1

moja próba odpowiedzi ... naprawdę nie lubią lambda ograniczający: S

def result_get_mutual(result): 
    return result_keep_mutual(
     result, 
     result.iterkeys(), 
     reduce(
      lambda current, incoming: 
       current.intersection(incoming), 
      map(
       lambda base_data: set(base_data[1].iterkeys()), 
       result.iteritems()))) 


def result_keep_mutual(result, base_dict, sub_dict_common): 
    return reduce(
     lambda current, base_data: 
      base_get_common(current, base_data, sub_dict_common), 
     result.iteritems(), 
     {}) 

def base_get_common(result, base_data, sub_dict): 
    result.update({ 
     base_data[0]: reduce(
      lambda result, sub_incoming: 
       base_rebuild_ping(result, sub_incoming, base_data[1][sub_incoming]), 
      sub_dict, 
      {}) 
     }); 

    return result; 

def base_rebuild_ping(result, sub, ping): 
    result.update({ sub: ping }) 

    return result 

print result_get_mutual({ 
    'key1': 
     { 
      'foo': 1233, 
      'bar': 1234, 
      'baz': 122 
     }, 
    'key2': 
     { 
      'foo': 113, 
      'bar': 333 
     } 
});