2016-10-19 11 views
-2

今年の早い時期にこの問題について非常に有益な答えが得られましたが、そこではパンダを使うことができました。今私は純粋なPythonでそれをする必要があります。このような辞書があり入れ子にされたタプルを入れ子にしたネストされたdictをキーとして使用する

inp = {((0, 0), 0): -99.94360791266038, 
     ((0, 0), 1): -1.1111111111107184, 
     ((1, 0), 0): -1.111111111107987, 
     ((1, 0), 1): -1.1111111111079839, 
     ((1, 0), 3): -1.111111111108079} 

は今、私はこのようなネストされた辞書でこれを変換したい:

out = {(0,0): {0: -99.94360791266038, 1: -1.1111111111107184}, 
     (1,0): {0: -1.111111111107987, 
       1: -1.1111111111079839, 
       3: -1.111111111108079} 

私は上品な言葉遣いを理解してこれを行うことができますどのように?私はちょうどそれの周りに私の頭を得ることができません。

答えて

3

私はdictのcomprenhesionでこれをしませんでした。ただ、単純なループを使用します。

out = {} 
for key, value in inp.items(): 
    k1, k2 = key 
    out.setdefault(k1, {})[k2] = value 

デモ:

>>> inp = {((0, 0), 0): -99.94360791266038, 
...  ((0, 0), 1): -1.1111111111107184, 
...  ((1, 0), 0): -1.111111111107987, 
...  ((1, 0), 1): -1.1111111111079839, 
...  ((1, 0), 3): -1.111111111108079} 
>>> out = {} 
>>> for key, value in inp.items(): 
...  k1, k2 = key 
...  out.setdefault(k1, {})[k2] = value 
... 
>>> from pprint import pprint 
>>> pprint(out) 
{(0, 0): {0: -99.94360791266038, 1: -1.1111111111107184}, 
(1, 0): {0: -1.111111111107987, 
      1: -1.1111111111079839, 
      3: -1.111111111108079}} 

dictの理解と同じことを行うには可能ですが、その後は上のキーをキーをソートし、グループにitertools.groupby()を使用する必要があります第1のタプル要素。ソートにはO(NlogN)時間がかかっており、上記のような単純なループは容易にそれを打ち消す。

それでも、完全性のために:

from itertools import groupby 
out = {g: {k[1]: v for k, v in items} 
     for g, items in groupby(sorted(inp.items()), key=lambda kv: kv[0][0])} 
+0

inp.items(): 'しかし、私は少し読みにくいと思う。 –

+0

@ PM2Ring:ええ、私はそれを使用したくなかったので、開梱の仕組みを説明しなければならないからです。 –

1

ナイーブソリューション:

my_dict = { 
      ((0, 0), 0): -99.94360791266038, 
      ((0, 0), 1): -1.1111111111107184, 
      ((1, 0), 0): -1.111111111107987, 
      ((1, 0), 1): -1.1111111111079839, 
      ((1, 0), 3): -1.111111111108079 
     } 

def get_formatted_dict(my_dict): 
    formatted_dict = {} 
    for k, v in my_dict.items(): 
     index_1, index_2 = k 
     if index_1 not in formatted_dict: 
      formatted_dict[index_1] = {} 
     formatted_dict[index_1][index_2] = v 
    return formatted_dict 

print(get_formatted_dict(my_dict)) 

出力:あなたは `(K1、K2)のために、値を持つ行を排除_could_

{(1, 0): {0: -1.111111111107987, 1: -1.1111111111079839, 3: -1.111111111108079}, (0, 0): {0: -99.94360791266038, 1: -1.1111111111107184}} 
+1

それほど素朴ではありません。唯一の違いは、私が['dict.setdefault()'メソッド(https://docs.python.org/3/library/stdtypes.html#dict.setdefault)を使ってあなたの 'index_1 not in formatted_dict:'テストと同じ動作です。 –

+0

どうやら、私はあなたの答えを後で見た。 –

関連する問題