蟒蛇。列出嵌套字典:奇怪的行为

时间:2018-11-02 17:18:05

标签: python python-3.x dictionary

我是Python 3.6用户。我面临着一个显而易见的简单任务:将list转换为dict。我看到了这个helpful question是在汲取灵感。

让我解释一下我的目标:从这样的对象列表开始:

class AObject():
def __init__(self, sp, sb, n):
    self.superset = sp
    self.subset   = sb
    self.number   = n

我想要一个这样的字典:d[superset][subset] = number

我的出发点是一个简单的清单:

s = set((('a','a1'),('a','a2'),('b','b1'),('b','b2'))) #set of tuples
o = [AObject(t[0], t[1], n) for t, n in zip(s, range(0,4))]

其长度为4。

现在,我以这种方式创建字典:

d = {x.superset: {x.subset : x.number} for x in o}

但是

d
Out[5]: {'a': {'a1': 1}, 'b': {'b1': 3}}

另外两个字典项目去哪里了?

使用以下相同的结果

d1 = dict(map(lambda x: (x.superset, {x.subset : x.number}), o))

同时带有for循环:

from collections import defaultdict
d2 = defaultdict(dict)
for x in o:
    d2[x.superset][x.subset] = x.number

d2
defaultdict(dict, {'a': {'a1': 1, 'a2': 0}, 'b': {'b1': 3, 'b2': 2}})

我的问题:

  • 我认为,当我使用dict理解时,以同样的方式对字典进行更新,如here所述,每个superset仅保留一个元素。我说的对吗?

  • 如何以pythonic方式构建嵌套字典?

1 个答案:

答案 0 :(得分:3)

您遇到的问题在这里:

d = {x.superset: {x.subset : x.number} for x in o}

任何时候只要要创建新的x.superset字典,它就会覆盖前一个-与

类似
d2 = { k:v for k,v in [ (1,4),(1,7),(1,9)]} # d2 == {1:9,} - last value to key 1 survives

您再包装一层的事实并不重要-如果您在dict-comp中提供多个相同的键,则您将获得覆盖行为-而不是update-behaviour。

您的

from collections import defaultdict
d2 = defaultdict(dict)
for x in o:
    d2[x.superset][x.subset] = x.number

与它的Pythonic一样。


defaultdict方法类似于(但更有效):

d2 = {}
for x in o:
    k = d2.setdefault(x.superset,{})
    k[x.subset] = x.number

# {'a': {'a1': 1, 'a2': 0}, 'b': {'b1': 3, 'b2': 2}}

dict comp方法类似于:

for x in o:
    d2[x.superset] = {x.subset:x.number}

# {'a': {'a1': 1}, 'b': {'b1': 3}}