我是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方式构建嵌套字典?
答案 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}}