填充嵌套字典

时间:2017-08-12 04:42:57

标签: python list dictionary nested tuples

我有很长的嵌套元组列表,我正在迭代并以某种方式附加,以便空字典:

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]

我的方法的问题是迭代失败,因为字典是空的开头或者嵌套的父级在dict中不存在。对我来说这很复杂。我无法在网上找到有关如何处理嵌套词典的大量信息,所以我认为在这里问一下应该没问题。

2 个答案:

答案 0 :(得分:5)

以下是使用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 line vs“for each ...”这是解压缩iterable中的项目。你也可以做到

for value, keys in longlist:

但是因为键也是可迭代的,所以如果将它包装在parens中,也可以解压缩它。

答案 1 :(得分:2)

如果没有深入研究您要做的事情,您可以将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] }

这比以前更具可读性。