使用Dict Comprehension将元组的元组转换成字典的Dict

时间:2019-10-19 18:07:16

标签: python python-3.x

我正在执行以下sqlite命令:

c.execute("SELECT surname,forename,count(*) from census_data group by surname, forename")

这样c.fetchall()如下:

(('Griffin','John', 7), 
 ('Griffin','James', 23), 
 ('Griffin','Mary',30), 
 ('Griffith', 'John', 4),
 ('Griffith','Catherine', 5)
)

是否可以使用dict理解构建以下形式的dict:

{'Griffin': {'John': 7, 'James': 23, 'Mary':30}, 'Griffith': {'John':4,'Catherine':5}}

据我所知:

counts = {s:(f,c) for s,f,c in c.fetchall()}

将覆盖值。我正在使用python 3。

5 个答案:

答案 0 :(得分:5)

尽管具有itertools.groupby魔法,但具有 dict理解力

from itertools import groupby

counts = {k: dict(_[1:] for _ in g) for k, g in groupby(c.fetchall(), key=lambda t: t[0])}
print(counts)

输出:

{'Griffin': {'John': 7, 'James': 23, 'Mary': 30}, 'Griffith': {'John': 4, 'Catherine': 5}}

答案 1 :(得分:4)

您可以在需要时使用collections.defaultdict自动创建内部字典:

from collections import defaultdict

data = (('Griffin','John', 7), 
 ('Griffin','James', 23), 
 ('Griffin','Mary',30), 
 ('Griffith', 'John', 4),
 ('Griffith','Catherine', 5)
)

out = defaultdict(dict)
for (name, first, value) in data:
    out[name][first] = value


# {'Griffin': {'John': 7, 'James': 23, 'Mary': 30}, 'Griffith': {'John': 4, 'Catherine': 5}}

答案 2 :(得分:2)

是的,像这样。

my_query = (('Griffin','John', 7), ('Griffin','James', 23), ('Griffin','Mary',30), ('Griffith', 'John', 4), ('Griffith','Catherine', 5) )

dict_query = {}
for key1, key2, value in my_query:
    if key1 not in dict_query:
        dict_query[key1] = {}
    dict_query[key1][key2] = value

Edit1

更优雅。

from collections import defaultdict 
dict_query = defaultdict(dict) 
for key1, key2, value in my_query:
    dict_query[key1][key2] = value

答案 3 :(得分:0)

除了defaultdict之外,您还可以使用字典方法setdefault()

dct = {}

for k1, k2, v2 in c.fetchall():
    v1 = dct.setdefault(k1, {})
    v1[k2] = v2

for k1, k2, v2 in c.fetchall():
    dct.setdefault(k1, {})[k2] = v2

结果:

{'Griffin': {'John': 7, 'James': 23, 'Mary': 30},
 'Griffith': {'John': 4, 'Catherine': 5}}

答案 4 :(得分:0)

您可以按住itertools.groupbyfunctools.itemgetter来解决它。

from operator import itemgetter
from itertools import groupby

result = { name: dict(v for _, v in values) for name, values in groupby(((x[0], x[1:]) for x in c.fetchall()), itemgetter(0))}
print(result)
# {'Griffin': {'John': 7, 'James': 23, 'Mary': 30}, 'Griffith': {'John': 4, 'Catherine': 5}}

外部循环在名称及其值之间分割数据,然后groupby(...)按名称折叠。内部循环只是用相应的值构建字典。