Python 填充嵌套字典

Python 填充嵌套字典,python,list,dictionary,nested,tuples,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[

我有一个很长的嵌套元组列表,我正在迭代并以某种方式追加这些元组,这样一个空字典:

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 = {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中不存在嵌套的父项。这对我来说越来越复杂。我在网上找不到关于如何处理嵌套字典的很多信息,所以我认为可以在这里提问。

如果不深入研究您正在尝试做的事情,您可以重写
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循环的头部解包项目,这样您就不必执行
每个[0]
每个[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] }

这比以前更具可读性。

无需深入研究您正在尝试执行的操作,您可以重写
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循环的头部解包项目,这样您就不必执行
每个[0]
每个[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] }

这比以前更具可读性。

这里有一个使用
集合的解决方案。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行vs“for each…”这是在iterable中解包项目。你也可以这么做

for value, keys in longlist:

但是,由于keys也是一个iterable,如果将其包装在paren中,也可以将其解包。

这里有一个使用集合的解决方案。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行vs“for each…”这是在iterable中解包项目。你也可以这么做

for value, keys in longlist:

但是,由于键也是一个可数,如果你把它包装成paren,你也可以把它解包。

dict={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))
?如果你能明确我可以帮助你解决问题。看看
(1,(a,b))
,迭代将创建
a:{}
b:{}
,这将成为
a:{b:{}
。然后,它将附加1,结果是
a:{b:{1}
。该过程在填充数值时重复。我在示例中放置了一个不连续的数字,因为真实世界的版本就是这样结束的,我正在处理数百个数据:/@JosephKim添加了进一步的改进。希望有帮助
dict={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))
?如果你能明确我可以帮助你解决问题。看看
(1,(a,b))
,迭代将创建
a:{}
b:{}
,这将成为
a:{b:{}
。然后,它将附加1,结果是
a:{b:{1}
。该过程在填充数值时重复。我在示例中放置了一个不连续的数字,因为真实世界的版本就是这样结束的,我正在处理数百个数据:/@JosephKim添加了进一步的改进。希望有帮助!结果很好。get函数正是我想要的。我已经接受了这个答案。谢谢@约瑟夫金很高兴我能帮上忙。干杯结果很好。get函数正是我想要的。我已经接受了这个答案。谢谢@约瑟夫金很高兴我能帮上忙。干杯我发现collections.defaultdict实际上是检查现有词典的更好方法。通过一些调整,我实际上能够解释长列表的更长版本:
longlist=[(1,(a,b,d,e,…),(2,(b,c,a,f,…),(3,(c,b,a,f,…)]
我发现collections.defaultdict实际上是检查现有词典的更好方法。通过一些调整,我实际上能够解释长列表的较长版本:
longlist=[(1,(a,b,d,e,…),(2,(b,c,a,f,…),(3,(c,b,a,f,…)]