我有一个数据列表,我在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'值缺失
答案 0 :(得分: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_dict
通过将输入字符串拆分为键和值来返回dict
。酷位是使用defaultdict
我们可以轻松地将其他键值附加到键上,而无需进行任何检查,即:
['h1_d1','h1_d2','h2_d3']
变为:{'h2': ['d3'], 'h1': ['d1', 'd2']}
而不是{'h2': ['d3'], 'h1': ['d2']}
然后我们结合从最里面开始向外生长的词汇。这是通过迭代外部字典的键,并用一个由该值键入的字典替换每个值,并且值是键,从内部字典对的值对。
答案 1 :(得分: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)
答案 2 :(得分: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']}}}}
答案 3 :(得分:0)
阅读该代码相当困难,但我认为在您创建新词典(...={}
)的行中,尤其是新的链接列表(...=[]
),您应该尝试以下内容:< / p>
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])
然后你确定你没有覆盖已存在的东西。
答案 4 :(得分:0)
已经提到了样式问题,所以我专注于功能。原始代码中的简单错误在最后一行。因为对于第一次出现的字典键序列,只需分配一个空列表,
的重要值domain.split( '_')[1]
丢了。 所以实际上没有覆盖,但是从未存储过缺失的值。填写空方括号,这个术语应该解决这个问题。