如何更正我的代码以生成嵌套字典?

时间:2015-06-21 17:03:20

标签: python dictionary

我正在尝试创建嵌套字典。我有一个元组列表(称为'kinetic_parameters'),如下所示:

('New Model','v7','k1',0.1)
('New Model','v8','k2',0.2)
('New Model','v8','k3',0.3)

我需要第二列是外键,而值是另一个字典,内键是第三列,值是第四列中的数字。

我目前有:

    for i in kinetic_parameters:
        dict[i[1]]={}
        dict[i[1]][i[2]]=i[3]

但是这段代码不会处理内部字典中的多个键,所以我丢失了一些信息。有人知道如何纠正我的问题吗?

我正在使用Python 2.7,我希望输出看起来像这样:

{'v7': {'k1': 0.1}, 'v8':{'k2':0.2, 'k3': 0.3}}

6 个答案:

答案 0 :(得分:3)

使用defaultdict,不要使用Makefile作为变量名,因为我们需要它来引用字典类型:

dict

这会自动创建词典。

答案 1 :(得分:2)

是的,如果在您使用现有字典之前已经看到主要("外部")键。或者反过来说:只有在不存在的情况下才创建嵌入式字典,然后添加值。这是逻辑,为了清晰起见使用元组赋值:

nested = dict()
for row in kinetic_parameters:
    _model, outkey, inkey, val = row
    if outkey not in d:
        nested[outkey] = dict()  
    nested[outkey][inkey] = val

或者您可以使用defaultdict跳过存在性检查,这可以根据需要创建新的嵌入式词典:

from collections import defaultdict
nested = defaultdict(dict)
for row in kinetic_parameters:
    _model, outkey, inkey, val = row
    nested[outkey][inkey] = val

答案 2 :(得分:1)

您可以使用dict理解来获取最后3项,然后使用reduce函数创建嵌套字典:

use std::cell::Cell;

fn main() {
    let board = vec![Cell::new(0), Cell::new(1), Cell::new(2)];

    for a in board.iter() {
        for b in board.iter() {
            a.set(a.get() + b.get());
        }
    }
    println!("{:?}", board);
}

这也适用于较长的列表:

>>> l=[('New Model','v7','k1',0.1),
... ('New Model','v8','k2',0.2),
... ('New Model','v8','k3',0.3)]
>>> 
>>> [reduce(lambda x,y:{y:x},p) for p in [i[1:][::-1] for i in l]]
[{'v7': {'k1': 0.1}}, 
 {'v8': {'k2': 0.2}}, 
 {'v8': {'k3': 0.3}}]

编辑:如果您想将字典作为主容器,可以使用>>> l=[('New Model','v7','k1',0.1,'c','5','r',9), ... ('New Model','v8','k2',0.2,'d','6'), ... ('New Model','v8','k3',0.3)] >>> [reduce(lambda x,y:{y:x},p) for p in [i[1:][::-1] for i in l]] [{'v7': {'k1': {0.1: {'c': {'5': {'r': 9}}}}}}, {'v8': {'k2': {0.2: {'d': '6'}}}}, {'v8': {'k3': 0.3}}] 中的生成器表达式将列表转换为字典:

dict

答案 3 :(得分:1)

在你的代码中重新初始化每个循环字典。您需要先初始化字典然后再添加项目

for i in kinetic_parameters:
        d[i[1]]={}
for i in kinetic_parameters:
        d[i[1]][i[2]]=i[3]

或在初始化之前检查

for i in kinetic_parameters:
        if d.get(i[1]) is None:
            d[i[1]]={}
        d[i[1]][i[2]]=i[3]

答案 4 :(得分:1)

kinetic_parameters = [('New Model','v7','k1',0.1),
                      ('New Model','v8','k2',0.2),
                      ('New Model','v8','k3',0.3)
                    ]

d = {}
for i in kinetic_parameters:
    if i[1] not in d.keys(): # Check if v7, v8 etc is present.
        d[i[1]] = {}         # Create an empty dict if absent
    d[i[1]][i[2]] = i[3]
print(d)

输出符合您的预期:

{'v7': {'k1': 0.1}, 'v8': {'k3': 0.3, 'k2': 0.2}}

答案 5 :(得分:1)

这是一个解决方案,我认为很容易理解:

import collections

kinetic_parameters = [
    ('New Model','v7','k1',0.1),
    ('New Model','v8','k2',0.2),
    ('New Model','v8','k3',0.3),
]

result = collections.defaultdict(dict)
for _, outter_key, inner_key, inner_value in kinetic_parameters:
    outter_value = {inner_key: inner_value}
    result[outter_key].update(outter_value)

在此解决方案中,我们对外部字典使用defaultdict。我们第一次遇到result[outter_key]时,将创建一个空字典并将其分配给该值。下一步是更新该值(内部字典)。

更新

如果您不想使用defaultdict

result = {}
for _, outter_key, inner_key, inner_value in kinetic_parameters:
    outter_value = {inner_key: inner_value}
    result.setdefault(outter_key, {})
    result[outter_key].update(outter_value)

setdefault方法创建一个新词典并仅首次分配给outter词典。