2017-08-12 199 views
0

我有我通过迭代,并以一定的方式附加这样一个空的字典嵌套元组的一个长长的清单:填充嵌套的字典

dict = {} 

将充满这样的:

dict = {a: {b:1,5,9,2,3}, b: {c:7,4,5,6,2,4}, c: {b:3,13,2,4,2}... } 

迭代将检查嵌套字典是否存在,如果是,则会附加值,否则,创建一个嵌套字典。我可怜的企图看起来是这样的:

longlist = [(1,(a,b)),(2,(b,c)), (3,(c,b)) ... ] 
dict = {} 
    for each in longlist: 
     if dict[each[1][0]][each[1][1]]: 
      dict[each[1][0]][each[1][1]].append(each[0]) 
     else: 
      dict[each[1][0]] = {} 
      dict[each[1][0]][each[1][1]] = each[0] 

请记住,这是一个简化版本,所以我有比值A,B,C,1,2,3在我的现实世界版本的更多。

我的方法存在的问题是,迭代失败,因为字典是空的开始或巢的父母不存在于字典中。对我而言,这变得越来越复杂。我无法在网上找到关于如何处理嵌套字典的大量信息,所以我认为在这里问问应该没问题。我需要帮助。

+0

'字典= {a:{b:1,5,9,2,3},b:{c:7,4,5,6,2,4},c:{b:3,13,2,4,2} ...]':你能否澄清一下这是如何形成的:'[(1,(a,b)),(2,(b,c)),(3,(c,b))] ''如果你可以清楚我可以帮忙解决问题, – crazyGamer

+0

看看'(1,(a,b))',迭代将创建'a:{}'和'b:{}',变成'a:{b:{}}',然后再追加1,得到'a:{b:{1}}'。例如,因为这是如何的原因l世界版本结束,我正在处理数百个数据:/ –

+0

@JosephKim添加了进一步的改进。希望能帮助到你! –

回答

3

下面是使用collections.defaultdict

import random 
import collections 
choices = ['a', 'b', 'c', 'd', 'e', 'f'] 

longlist = [] 
for i in range(1, 101): 
    longlist.append((i, tuple(random.sample(choices, 2)))) 

print longlist 

final = collections.defaultdict(lambda: collections.defaultdict(list)) 

for value, (key1, key2) in longlist: 
    final[key1][key2].append(value) 


print final 

一般的解决方案,我会改变你的代码的方式是首先确保存在的嵌套字典(collections.defaultdict需要照顾这对你),然后总是追加一次。

喜欢的东西

for value (key1, key2) in longlist: 
    if not your_dict.get(key1): 
     your_dict[key1] = {} 
    if not your_dict.get(key1).get(key2): 
     your_dict[key1][key2] = [] 
    your_dict[key1][key2].append(value) 

也不是线路与“每个...“这是拆包在迭代的项目。你也可以做

for value, keys in longlist: 

但由于键是一个迭代,以及,你可以,如果你在括号把它包起来解开它。

+0

我发现collections.defaultdict实际上是检查现有字典的更好方法。经过一些调整,我实际上可以解释longlist的更长版本:'longlist = [(1,(a,b,d,e,...)),(2,(b,c,a ,f,...)),(3,(c,b,a,f,...))...]' –

1

没有研究多到你正在尝试做的,你可以重写你的if声明如果不存在密钥不引发错误:

if dict_.get(each[1][0], {}).get(each[1][1], None): 
    dict_[each[1][0]][each[1][1]].append(each[0]) 

dict.get是一个非常有用的功能如果给定的键不存在,它将返回一个默认值。

此外,它似乎你希望列表存在。在else区块中,您是否意味着要这么做?

dict_[each[1][0]][each[1][1]] = [each[0]] 

这将创建一个单一元素的列表,所以现在dict[...][...].append(...)将工作。

我也建议不要使用dict来命名变量。它影响了内置的课程。

进一步的改进可能包括解压缩for循环头部中的项目,因此您不必执行each[0],each[1]等等。你可以使用类似:

for idx, pair in longlist: 
    x, y = pair # unpack each pair now 
    ... 

全面上市:

dict_ = {} 
for idx, pair in longlist: 
    x, y = pair 
    if dict_.get(x, {}).get(y, None): 
     dict_[x][y].append(idx) 

    else: 
     dict_[x] = {y : [idx] } 

这是比以前更具有可读性。

+1

这很好。 get函数是我正在寻找的。我已经接受了这个答案。谢谢! –

+0

@JosephKim很高兴我能帮到你。干杯! –