2012-04-17 2 views
5

私は、フォームのテーブルを持っている:テーブルを階層的な辞書に変換しますか?

A1, B1, C1, (value) 
A1, B1, C1, (value) 
A1, B1, C2, (value) 
A1, B2, C1, (value) 
A1, B2, C1, (value) 
A1, B2, C2, (value) 
A1, B2, C2, (value) 
A2, B1, C1, (value) 
A2, B1, C1, (value) 
A2, B1, C2, (value) 
A2, B1, C2, (value) 
A2, B2, C1, (value) 
A2, B2, C1, (value) 
A2, B2, C2, (value) 
A2, B2, C2, (value) 

私は、フォームの辞書としてのpythonで作業したいと思います:

H = { 
    'A1':{ 
     'B1':{ 
      'C1':[],'C2':[],'C3':[] }, 
     'B2':{ 
      'C1':[],'C2':[],'C3':[] }, 
     'B3':{ 
      'C1':[],'C2':[],'C3':[] } 
    }, 
    'A2':{ 
     'B1':{ 
      'C1':[],'C2':[],'C3':[] }, 
     'B2':{ 
      'C1':[],'C2':[],'C3':[] }, 
     'B3':{ 
      'C1':[],'C2':[],'C3':[] } 
    } 
} 

H[A][B][C]は、特定のユニークなリストを生成するようにするため値。小規模の辞書の場合は、上記のように事前に構造を定義するだけですが、辞書キーを事前に指定することなく、テーブルを繰り返して辞書を構築する効率的な方法を探しています。

+5

あなたは常にA、B、C値の3倍を調べますか?そうであれば、それらのトリプルをキーとして使用する単一の「dict」を使う方がよいでしょう。 –

答えて

8
input = [('A1', 'B1', 'C1', 'Value'), (...)] 

from collections import defaultdict 

tree = defaultdict(lambda: defaultdict(lambda: defaultdict(list))) 
#Alternatively you could use partial() rather than lambda: 
#tree = defaultdict(partial(defaultdict, partial(defaultdict, list))) 

for x, y, z, value in input: 
    tree[x][y][z].append(value) 
+1

tableがテキストファイルの場合、 '' 'open(" table ")をfile:' '' input = [line in file for] ''としたいでしょう。 –

+2

ここでラムダを使用する代わりに '' functools.partial() ''を使用することです:()部分(defaultdict、部分(defaultdict、リスト)) ''ツリー= defaultdictを '' - 私はこの明確に見つけるが、それは可能性がありますだけ私です。 –

+0

@Lattyware興味深いことに、ありがとう。 –

2
d = {} 
for (a, b, c, value) in your_table_of_tuples: 
    d.setdefault(a, {}).setdefault(b,{}).setdefault(c,[]).append(value) 
+0

なぜ '' setdefault() ''を '' defaultdict''よりも使うのですか? –

+0

@Lattyware:どうしてですか? – vartec

+0

私はそれがあなたがそれを使うとき、それはもっと醜いと主張するでしょう。 –

4

あなたが唯一のアクセスH [A] [B] [C](つまり、決してH [A]オーデルH [A] [B]のみ)場合は、私がお勧めしたいですIMOクリーナーソリューション:defaultdictとしてタプルを使用するインデックス:

from collections import defaultdict 
h = defaultdict(list) 
for a, b, c, value in input: 
    h[a, b, c].append(value) 
+0

これは非常に有効な(そしてエレガントな)ソリューションですが、サブディクショナリに別々にアクセスする必要はありません。 (余分な字下げや不必要な括弧を削除するために編集し、変数名をPEP-8に変更する)。 –

+0

このソリューションを投稿していただきありがとうございます。この場合、私はサブディクショナリにアクセスする必要がありますが、私はその質問にそれを指定しませんでした。このケースが将来存在する場合、これは非常にエレガントになります。 –