2011-05-17 112 views
2

我有這個多維字典:的Python - Unflatten字典

a = {'a' : 'b', 'c' : {'d' : 'e'}} 

和書寫簡單的功能扁平化是字典:

def __flatten(self, dictionary, level = []): 
    tmp_dict = {} 
    for key, val in dictionary.items(): 
     if type(val) == dict: 
      tmp_dict.update(self.__flatten(val, level + [key])) 
     else: 
      tmp_dict['.'.join(level + [key])] = val 
    return tmp_dict 

通話用字典a這個功能我在結果得到後:

{'a' : 'b', 'c.d' : 'e'} 

現在,在對這個扁平的字典作出幾個指示後,我需要建立新的,從這個扁平的多維詞典。例如:

>> unflatten({'a' : 0, 'c.d' : 1)) 
{'a' : 0, 'c' : {'d' : 1}} 

我唯一的問題是我不具備的功能unflatten :)
任何人都可以在這方面幫助?我不知道該怎麼做。

編輯:

又如:

{'a' : 'b', 'c.d.e.f.g.h.i.j.k.l.m.n.o.p.r.s.t.u.w' : 'z'} 

後應unflatten:

{'a': 'b', 'c': {'d': {'e': {'f': {'g': {'h': {'i': {'j': {'k': {'l': {'m': {'n': {'o': {'p': {'r': {'s': {'t': {'u': {'w': 'z'}}}}}}}}}}}}}}}}}}} 

而另:

{'a' : 'b', 'c.d' : 'z', 'c.e' : 1} 

要:

{'a' : 'b', 'c' : {'d' : 'z', 'e' : 1}} 

這大大增加了工作的難度,我知道。這就是爲什麼我有這個問題,並發現小時無解..

+0

我真的不能明白爲什麼' 'C':{ 'd': 'E'}''變成 'CD': 'e'',如果你有'' C ':{'f':'g','d':'e'}' – neurino 2011-05-17 22:00:49

+0

Then'{'c':{'f':'g','d':'e'}}'' 'cf':'g','cd':'e'}':) – Galmi 2011-05-17 22:12:39

回答

6
def unflatten(dictionary): 
    resultDict = dict() 
    for key, value in dictionary.iteritems(): 
     parts = key.split(".") 
     d = resultDict 
     for part in parts[:-1]: 
      if part not in d: 
       d[part] = dict() 
      d = d[part] 
     d[parts[-1]] = value 
    return resultDict 
+0

這個實現比我的更好,因爲它處理輸入{'a':'b','c.d.e':1}和任何更深的嵌套(更多點)。我害怕降低自己的答案...不知道會發生什麼。 ;) – 2011-05-17 22:05:39

+0

它完全按照我的需要工作。謝謝你,你救了我一整夜的思考:) – Galmi 2011-05-17 22:35:29

1

作一個粗略的草稿(可以使用在變量名的選擇稍有起色,也許魯棒性,但它工作在給出的例子):

def unflatten(d): 
    result = {} 
    for k,v in d.iteritems(): 
     if '.' in k: 
      k1, k2 = k.split('.', 1) 
      v = {k2: v} 
      k = k1 
     result[k] = v 
    return result 
+0

Dangit!即使我有足夠的人承認它不如另一個好(Messa在這種情況下),我也不能低估自己的答案。 – 2011-05-17 22:08:39

+0

你可以刪除它,我認爲;) – 2011-05-17 22:19:12

2
from collections import defaultdict 
def unflatten(d): 
    ret = defaultdict(dict) 
    for k,v in d.items(): 
     k1,delim,k2 = k.partition('.') 
     if delim: 
      ret[k1].update({k2:v}) 
     else: 
      ret[k1] = v 
    return ret 
+0

使用遞歸+1,但不正確:例如''{'a.b':0,'a.c':1}''將返回''{'a':{'c':1}}''可以使用''ret [k1] .update(...)''代替。 – 2011-05-17 22:17:28

+0

@Lucasmus,是的,我現在把它改回原來的答案。我暫時認爲它可以簡化 – 2011-05-17 22:20:42