猿问

Python。嵌套字典列表:奇怪的行为

我是 Python 3.6 用户。我面临着一个明显的简单任务:将 a 转换list为 a dict。我看到了这个有助于获得灵感的问题。


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


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}})

我的问题:


我觉得同样的方式,当我使用字典理解只用1个元素每次发生的词典的更新superset作为解释这里。我对吗?


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


牧羊人nacy
浏览 167回答 1
1回答

万千封印

您遇到的问题在这里: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 中提供多个相同的键,你会得到覆盖行为 - 而不是更新行为。您的from collections import defaultdictd2 = defaultdict(dict)for x in o:    d2[x.superset][x.subset] = x.number就像它得到的那样pythonic。defaultdict-aproach 类似于(但更有效):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}}
随时随地看视频慕课网APP

相关分类

Python
我要回答