2016-09-14 105 views
0

我有像這樣包含項列出的清單和值:讓嵌套的字典,unflatten

[ 
    ['mounts:device', '/dev/sda3'], 
    ['mounts:fstype:[0]', 'ext1'], 
    ['mounts:fstype:[1]', 'ext3'] 
] 

那麼我可以列表中很容易地改變這個

(名單的arent分隔「:」)

[ 
    ['mounts:device', '/dev/sda3'], 
    ['mounts:fstype[0]', 'ext1'], 
    ['mounts:fstype[1]', 'ext3'] 
] 

任何適合對於這個問題更好:
問題是創建一個字典:

{ 
'mounts': { 
    'device': '/dev/sda3', 
    'fstype': [ 
     'ext1', 
     'ext3' 
    ] 
} 

它也應該可以在列表中列出了例如:

['mounts:test:lala:fstype[0][0]', 'abc'] 

['mounts:test:lala:fstype:[0]:[0]', 'abc'] 

這是我到目前爲止有:基於

def unflatten(pair_list): 
    root = {} 
    for pair in pair_list: 
     context = root 
     key_list = pair[0].split(':') 
     key_list_last_item = key_list.pop() 
     for key in key_list: 
      if key not in context: 
       context[key] = {} 
      context = context[key] 
     context[key_list_last_item] = pair[1] 
    return root 

這個回答https://stackoverflow.com/a/18648007/5413035,但根據要求,我需要recursivness和列表中的組合

預先感謝

+0

什麼問題?請參閱:[我如何問一個好問題?](http://stackoverflow.com/help/how-to-ask) –

+0

問題是如何實現unlatlatten到嵌套字典下面的函數不工作的列表 – Skeec

+0

列表示例中的列表應該是什麼樣的字典?請[編輯]你的問題,並告訴我們。 – martineau

回答

0
input1=[ 
    ['mounts:device', '/dev/sda3'], 
    ['mounts:fstype:[0]', 'ext1'], 
    ['mounts:fstype:[1]', 'ext3'] 
] 
input2={x[1]:x[0].split(':')[1] for x in input1} 
input3=['ext3', 'ext1', '/dev/sda3'] 
input4=['fstype', 'fstype', 'device'] 
res={} 
for x,y in zip(input3, input4): 
    res.setdefault(y,[]).append(x) 
res1=res.keys() 
res2=res.values() 
res3=[x[0] for x in res2 if len(x)==1]+[x for x in res2 if len(x)>1] 
result=dict(zip(res1,res3)) 

print result 

輸出:

{'device': '/dev/sda3', 'fstype': ['ext3', 'ext1']} 
+0

錯誤輸出OP需要這樣:{ '安裝':{ '設備': '的/ dev/sda3的', '的fstype':[ 'EXT1', 'EXT3' ] }即不使用列表當不需要('/ dev/sda3') – Saksow

+0

@Saksow,更正 –

1

下面是一個使用dict的溶液:

import collections 

def tree(): 
    return collections.defaultdict(tree) 


def unflatten(pair_list): 
    root = tree() 
    for mount, path in pair_list: 
     parts = mount.split(":") 
     curr = root 
     for part in parts[:-1]: 
      index = int(part[1:-1]) if part[0] == "[" else part 
      curr = curr[index] 
     part = parts[-1] 
     index = int(part[1:-1]) if part[0] == "[" else part 
     curr[index] = path 
    return root 

用下面的輸入:

pair_list = [ 
    ['mounts:device', '/dev/sda3'], 
    ['mounts:fstype:[0]', 'ext1'], 
    ['mounts:fstype:[1]', 'ext3'], 
    ['mounts:test:lala:fstype:[0]:[0]', 'abc'] 
] 

您將獲得:

{ 
    "mounts": { 
     "fstype": { 
      "0": "ext1", 
      "1": "ext3" 
     }, 
     "test": { 
      "lala": { 
       "fstype": { 
        "0": { 
         "0": "abc" 
        } 
       } 
      } 
     }, 
     "device": "/dev/sda3" 
    } 
} 

然後你可以使用遞歸函數make_list波紋管把整數索引的list

def make_list(root): 
    if isinstance(root, str): 
     return root 
    keys = list(root.keys()) 
    if all(isinstance(k, int) for k in keys): 
     values = [None] * (max(keys) + 1) 
     for k in keys: 
      values[k] = make_list(root[k]) 
     return values 
    else: 
     return {k: make_list(v) for k, v in root.items()} 

這裏是與pair_list結果:

flat = unflatten(pair_list) 
flat = make_list(flat) 

您將獲得:

{'mounts': {'device': '/dev/sda3', 
      'fstype': ['ext1', 'ext3'], 
      'test': {'lala': {'fstype': [['abc']]}}}} 

它是罰款?

+0

是的,很好,謝謝:) – Skeec