1

dict内にdictを作成しているデータのリストがあり、期待どおりに構造化されていますが、どこかで上書きされています。どこにあるのかわかりません。

a=['t1_h1','t2_h2']
b=['h1_d1','h1_d2','h2_d3']
c=['d1_dom1','d2_dom2','d3_dom3']
d=['dom1_a','dom1_b','dom2_a','dom2_b','dom3_a','dom3_b']

このコードを使ってみました

for item in a:
f[item.split('_')[0]]={}
for hypercube in b:
    if item.split('_')[1] in hypercube:#h1 in b

        f[item.split('_')[0]][item.split('_')[1]]={}

        for dimension in c:
            if hypercube.split('_')[1] in dimension:#d1 in c 
                f[item.split('_')[0]][item.split('_')[1]][hypercube.split('_')[1]]={}
                for domain in d:
                    if dimension.split('_')[1] in domain:#dom1 in d
                        if f[item.split('_')[0]][item.split('_')[1]][hypercube.split('_')[1]].has_key(dimension.split('_')[1]):
                            f[item.split('_')[0]][item.split('_')[1]][hypercube.split('_')[1]][dimension.split('_')[1]].append(domain.split('_')[1])
                        else:
                            f[item.split('_')[0]][item.split('_')[1]][hypercube.split('_')[1]][dimension.split('_')[1]]=[domain.split('_')[1]]

実際、私はこの形式で印刷しようとしています。

{'t1': {'h1': {'d1': {'dom1': ['a', 'b']}, 'd2': {'dom2': ['a', 'b']}}},
     't2': {'h2': {'d3': {'dom3': ['a', 'b']}}}}

しかし、私が得ている出力は次のとおりです。

{'t2': {'h2': {'d3': {'dom3': ['a','b']}}}, 't1': {'h1': {'d2': {'dom2': ['a','b']}}}}

しかし、最後のものを変更した後、't1''d1'の値が欠落しています

4

5 に答える 5

2

これは使用するのに適したケースだと思いますdefaultdict

from collections import defaultdict

def new_dict(items):
    items = [i.split('_') for i in items]
    d = defaultdict(list)
    for k, v in items:
        d[k].append(v)
    return dict(d)

def combine(x,y):
    for i in x:
        x[i] = dict((j,y[j]) for j in x[i])
    return x

a, b, c, d = [new_dict(i) for i in [a, b, c, d]]

c=combine(c,d)
b=combine(b,c)
a=combine(a,b)
print a
#Output:
{'t2': {'h2': {'d3': {'dom3': ['a', 'b']}}},
't1': {'h1': {'d2': {'dom2': ['a', 'b']}, 'd1': {'dom1': ['a', 'b']}}}}

new_dictdict入力文字列をキーと値に分割してa を返します。クールな点は、 を使用defaultdictすることで、チェックを行うことなく、追加のキー値をキーに簡単に追加できることです。

['h1_d1','h1_d2','h2_d3']なる:{'h2': ['d3'], 'h1': ['d1', 'd2']}およびない{'h2': ['d3'], 'h1': ['d2']}

次に、最も内側から外側に向かって辞書を結合します。これは、外部ディクショナリのキーを反復処理し、各値をその値でキー付けされた dict に置き換え、値がキーであり、内部ディクショナリの値のペアであることによって機能します。

于 2012-06-11T13:08:11.537 に答える
1

forループをネストするのではなく、各リストa、b、c、およびdを処理するときに、for検索をネストして、fにさらに深いレベルを追加します。これにより、目的の出力が得られます。

f = {}
for item in a:
    ak1,ak2 = item.split('_')
    f[ak1] = {ak2:{}}
for item in b:
    bk1,bk2 = item.split('_')
    next(f[akey][bk1] 
            for akey in f 
                if bk1 in f[akey])[bk2] = {}
for item in c:
    ck1,ck2 = item.split('_')
    next(f[akey][bkey][ck1] 
            for akey in f 
                for bkey in f[akey] 
                    if ck1 in f[akey][bkey])[ck2] = []
for item in d:
    dk1,dk2 = item.split('_')
    next(f[akey][bkey][ckey][dk1] 
            for akey in f 
                for bkey in f[akey]
                    for ckey in f[akey][bkey]
                        if dk1 in f[akey][bkey][ckey]).append(dk2)

import pprint
pprint.pprint(f)

プリント:

{'t1': {'h1': {'d1': {'dom1': ['a', 'b']}, 'd2': {'dom2': ['a', 'b']}}},
 't2': {'h2': {'d3': {'dom3': ['a', 'b']}}}}
于 2012-06-11T13:10:10.677 に答える
1

たぶん、コードを単純化する必要がありますか? これを試して:

def pack_to_tree(*lists):

    split_ = lambda l: (i.split('_',1) for i in l)

    # last level
    result = {}
    for k, v in split_(lists[-1]):
        result.setdefault(k, []).append(v)

    # other levels
    for d in lists[-2::-1]:
        subresult = {}
        for k, v in split_(d):
            subresult.setdefault(k, {})[v] = result[v]
        result = subresult
    return result

a = ['t1_h1', 't2_h2']
b = ['h1_d1', 'h1_d2', 'h2_d3']
c = ['d1_dom1', 'd2_dom2', 'd3_dom3']
d = ['dom1_a', 'dom1_b', 'dom2_a', 'dom2_b', 'dom3_a', 'dom3_b']

print pack_to_tree(a, b, c, d)
于 2012-06-11T13:06:50.220 に答える
0

そのコードを読むのはかなり難しいですが、新しい辞書 ( ...={}) と特に新しい連結リスト ( ...=[]) を作成する行では、次のようなことを試してみるべきだと思います:

if (not  f[item.split('_')[0]][item.split('_')[1]][hypercube.split('_')[1]][dimension.split('_')[1]]):
   f[item.split('_')[0]][item.split('_')[1]][hypercube.split('_')[1]][dimension.split('_')[1]]=[]
f[item.split('_')[0]][item.split('_')[1]][hypercube.split('_')[1]][dimension.split('_')[1]].append(domain.split('_')[1])

そうすれば、すでに存在するものを上書きしていないことを確信できます。

于 2012-06-11T12:55:37.780 に答える
0

スタイルの問題は既に述べたので、私は機能性に集中します。元のコードの単純なバグは最後の行にあります。ディクショナリ キー シーケンスの最初の出現では、単に空のリストが割り当てられるため、重要な値

ドメイン.スプリット('_')[1]

失われます。したがって、実際には上書きはありませんが、欠損値は保存されませんでした。空の角括弧をこの用語で埋めると、これが修正されます。

于 2012-06-11T13:41:41.117 に答える