2015-06-21 22 views
4

我想創建一個嵌套字典。我有元組(稱爲「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}} 
+0

新字典應該如何顯示? – nu11p01n73R

+0

你期望輸出什麼?什麼是你的Python版本? – Kasramvd

+0

你已經展示了沒有列表的列表,它是三元組 – Totem

回答

1

在每個循環字典的代碼中重新初始化。你需要初始化字典,然後再初始化

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

這不是一般的方法! – Kasramvd

1

您可以使用字典解析來獲得最後3個項目,然後使用reduce函數來創建一個嵌套的字典:

>>> 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用生成器表達式到您的列表轉換成詞典:

>>> g=[reduce(lambda x,y:{y:x},p) for p in [i[1:][::-1] for i in l]] 
>>> dict(next(i.iteritems()) for i in g) 
{'v8': {'k3': 0.3}, 'v7': {'k1': {0.1: {'c': {'5': {'r': 9}}}}}} 
+0

我想op正在尋找一本字典而不是名單。 – nu11p01n73R

+0

@ nu11p01n73R固定感謝指出! – Kasramvd

+0

嵌套理解+高階函數=不可讀。 OP沒有要求一個通用的解決方案。 – Kevin

3

使用defaultdict,並且不使用dict作爲變量名,因爲我們需要引用字典類型:

import collections 
d = collections.defaultdict(dict) 
for i in kinetic_parameters: 
    d[i[1]][i[2]]=i[3] 

這將自動創建字典。

+2

不使用python類型名稱作爲變量名稱是_always_好建議。 – alexis

+1

@alexis:確實。 – Kevin

+0

對於更長的列表,這將失敗! – Kasramvd

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) 

輸出爲您所期望的前添加項目

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

或檢查:

{'v7': {'k1': 0.1}, 'v8': {'k3': 0.3, 'k2': 0.2}} 
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 
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字典僅首次。