2011-12-22 21 views
2

辞書の値を別の辞書に追加したいと思います。例えば:私たちは辞書の値を別の辞書に追加する

をadictする{1: {'a': 3, 'b': 9, 'c': 23}}を追加した場合

adict = {1: {'a': 13, 'b': 19, 'c': 15}, 2: {'a': 7, 'b': 2, 'c': 0}} 

はその後adictは今、次のようになります。

{1: {'a': 16, 'b': 28, 'c': 38}, 2: {'a': 7, 'b': 2, 'c': 0}} 

我々は{3: {'a': 4}}を追加する場合は、adictが今のようになります。

{1: {'a': 16, 'b': 28, 'c': 38}, 2: {'a': 7, 'b': 2, 'c': 0}, 3: {'a': 4}} 

追加する場合は{2: {'a': 1, 'b': 8, 'c': 27, 'd': 11}}

その後adictが今のようになります。

{1: {'a': 16, 'b': 28, 'c': 38}, 2: {'a': 8, 'b': 10, 'c': 27, 'd': 11}, 3: {'a': 4}} 

これを行うための最善の方法は何ですか?

+0

「+」演算子を使用して計算します。 –

+1

@Chris:悲しいことに、それは動作しません... – Blender

+1

この操作はどのくらい深く入れ子ですか? adictが '{1:{'a':{'foo':13、 'bar':11、...}、 'b':anotherdict、...}}'の場合はどうなりますか? – kojiro

答えて

6

シンプルな再帰関数:

>>> adict = {1: {'a': 13, 'b': 19, 'c':15}, 2: {'a': 7, 'b': 2, 'c':0}} 
>>> def dict_add(a,b): 
... a = a.copy() 
... for k,v in b.items(): 
...  if isinstance(v,(dict,)): 
...  a[k] = dict_add(a.get(k,{}),v) 
...  else: 
...  a[k] = a.get(k,0) + v 
... return a 
... 
>>> dict_add(adict,{1: {'a': 3, 'b': 9, 'c': 23}}) 
{1: {'a': 16, 'c': 38, 'b': 28}, 2: {'a': 7, 'c': 0, 'b': 2}} 
>>> dict_add(dict_add(adict,{1: {'a': 3, 'b': 9, 'c': 23}}),{3:{'a':4}}) 
{1: {'a': 16, 'c': 38, 'b': 28}, 2: {'a': 7, 'c': 0, 'b': 2}, 3: {'a': 4}} 
+0

Heh、私はあなたのコードを長期的にあなたのものに変えてしまいました。 +1私から – Blender

+0

私のページはリフレッシュされていなかったので、私は私の投稿した後まであなたの解決策を見ていないだろう。私たちの答えがどれくらい近いのかを実証したのですが、私はpythonに関する大きな好きなものの一つが、[代替](http://en.wikipedia.org/wiki)とは対照的に、アイデアの表現の収束であると思います/ There's_more_than_one_way_to_do_it) – MattH

+0

ゆるいタイピングは、論理的なアイデアの流れです。私はこれをC++でやっているとは想像もできません。 – Blender

3

これはおそらく、非常に非効率的であるが、ここで私が思い付いたものです:

>>> adict = {1: {'a': 13, 'b': 19, 'c':15}, 2: {'a': 7, 'b': 2, 'c':0}} 
>>> bdict = {1: {'a': 3, 'b': 9, 'c': 23}} 
>>> 
>>> print dict_add(adict, bdict) 
{1: {'a': 16, 'c': 38, 'b': 28}, 2: {'a': 7, 'c': 0, 'b': 2}} 
0

この本のコードの結果を実行する

def dict_add(a, b): 
    result = dict(a) 

    for key, value in b.items(): 
    if type(value) != dict: 
     result[key] = result.get(key, 0) + value 
    else: 
     result[key] = dict_add(result.get(key, {}), value) 

    return result 

ここに機能的な解決策があります。 rec_add関数は、任意にネストされた辞書で求められることを行います。

def combine(f, d1, d2): 
    """Create a new dict combining d1 and d2. 

    Keys appearing only in one of the input dict are copied unmodified. Values 
    with matching keys are combined using f and copied in the output dict.""" 

    keys = set(d1.keys() + d2.keys()) 
    out = { } 
    for key in keys: 
     if key in d1: 
      if key in d2: 
       out[key] = f(d1[key], d2[key]) 
      else: 
       out[key] = d1[key] 
     else: 
      out[key] = d2[key] 
    return out 

def rec_combine(f, d1, d2): 
    """Recursively combine all dicts.""" 

    def aux(v1, v2): 
     if isinstance(v1, (dict,)) and isinstance(v2, (dict,)): 
      return rec_combine(f, v1, v2) 
     else: 
      return f(v1, v2) 

    return combine(aux, d1, d2) 

def rec_add(d1, d2): 
    """Recursively sum values in d1 and d2.""" 
    return rec_combine(lambda x, y: x + y, d1, d2) 
関連する問題