2011-10-10 105 views
2

我有一組數據,看起來與此類似:轉換列表中嵌套的列表和類型的字典

[ {"name":"item.key" , "value":"value"}, 
    {"name":"item.key2" , "value":"value2"}, 
    {"name":"item.list.0" , "value":"listValue1"}, 
    {"name":"item.list.1" , "value":"listValue2"}, 
    {"name":"item.list.2" , "value":"listValue3"},· 
    {"name":"item.list2.0.key1" , "value":"list2Key1Value"}, 
    {"name":"item.list2.0.key2" , "value":"list2Key2Value"}, 
    {"name":"item.list2.0.key3" , "value":"list2Key3Value"},· 
    {"name":"item.list3.0.key1" , "value":"list3Key1Value"}, 
    {"name":"item.list3.0.key2" , "value":"list3Key2Value"}, 
    {"name":"item.list3.0.key3" , "value":"list3Key3Value"}, 
    {"name":"other.key" , "value":"otherKeyValue"} 
] 

名字被從名單包含http://stardict.sourceforge.net/Dictionaries.php下載和嵌套數據夷爲平地。我現在想把它重新放回到字典和列表中(如適用)。

到目前爲止,我有這樣的:

obj = {} 
def addObj(o, path, value): 
    if len(path) > 1: 
     o = o.setdefault(path.pop(0), {}) 
     addObj(o, path, value) 
    else: 
     o[path.pop(0)] = value 

for item in data: 
    parts = item['name'].split(".") 
    addObj(obj, parts, item['value']) 

將產生這樣的:

{'item': { 
    'key': 'value', 
    'key2': 'value2', 
    'list': { 
     '0': 'listValue1', 
     '1': 'listValue2', 
     '2': 'listValue3'}, 
    'list2': { 
     '0': { 
      'key1': 'list2Key1Value', 
      'key2': 'list2Key2Value', 
      'key3': 'list2Key3Value'} 
    }, 
    'list3': { 
     '0': { 
      'key1': 'list3Key1Value', 
      'key2': 'list3Key2Value', 
      'key3': 'list3Key3Value'} 
    } 
}, 
'other': {'key': 'otherKeyValue'} 
} 

但現在,我想是有都可以強制轉換爲整數轉換爲密鑰的任何字典列表,所以我的最終輸出看起來更像:

{'item': { 
    'key': 'value', 
    'key2': 'value2', 
    'list': [ 
     'listValue1', 
     'listValue2', 
     'listValue3'], 
    'list2': [{'key1': 'list2Key1Value', 
      'key2': 'list2Key2Value', 
      'key3': 'list2Key3Value'}], 
    'list3': [{'key1': 'list3Key1Value', 
      'key2': 'list3Key2Value', 
      'key3': 'list3Key3Value'}] 
}, 
'other': {'key': 'otherKeyValue'} 
} 

有關如何完成此任務的任何建議?

+0

爲什麼不保留原有的數據身邊? –

回答

1

這可能不是這樣做的最有效的方式,但是......

import pprint 

data = [{"name":"item.key" , "value":"value"}, 
    {"name":"item.key2" , "value":"value2"}, 
    {"name":"item.list.0" , "value":"listValue1"}, 
    {"name":"item.list.1" , "value":"listValue2"}, 
    {"name":"item.list.2" , "value":"listValue3"}, 
    {"name":"item.list2.0.key1" , "value":"list2Key1Value"}, 
    {"name":"item.list2.0.key2" , "value":"list2Key2Value"}, 
    {"name":"item.list2.0.key3" , "value":"list2Key3Value"}, 
    {"name":"item.list3.0.key1" , "value":"list3Key1Value"}, 
    {"name":"item.list3.0.key2" , "value":"list3Key2Value"}, 
    {"name":"item.list3.0.key3" , "value":"list3Key3Value"}, 
    {"name":"other.key" , "value":"otherKeyValue"}] 

obj = {} 
def addObj(o, path, value): 
    if len(path) > 1: 
     o = o.setdefault(path.pop(0), {}) 
     addObj(o, path, value) 
    else: 
     o[path.pop(0)] = value 

for item in data: 
    parts = item['name'].split(".") 
    addObj(obj, parts, item['value']) 

# this function assumes all keys are strings 
def convert(obj): 
    if isinstance(obj, dict): 
     if all(key.isdigit() for key in obj.keys()): 
      return [convert(obj[key]) 
        for key in sorted(obj.keys(), key=int)] 
     return dict((key, convert(value)) for key, value in obj.items()) 
    return obj 

pprint.pprint(convert(obj)) 

產生以下輸出中:

{'item': {'key': 'value', 
      'key2': 'value2', 
      'list': ['listValue1', 'listValue2', 'listValue3'], 
      'list2': [{'key1': 'list2Key1Value', 
        'key2': 'list2Key2Value', 
        'key3': 'list2Key3Value'}], 
      'list3': [{'key1': 'list3Key1Value', 
        'key2': 'list3Key2Value', 
        'key3': 'list3Key3Value'}]}, 
'other': {'key': 'otherKeyValue'}} 
1

您可以更改genexp,以更好地滿足您的需求(這可能不是你的真實數據),但是,將工作:

for v in d.values(): 
    for key in (i for i in v if i.startswith('list')): 
     v[key] = list(v[key].values()) 

現在d字典有你想要

1

的內容您

map(int, your_dict.keys()) 

,這將產生一個:可以通過所有詞典使用該遞歸走,並檢查是否所有的鍵可以轉換爲整數如果其中一個密鑰無法轉換爲int

請注意,這不會檢查密鑰是連續整數還是從0開始,因此當您將字典轉換爲列表時,可能浪費大量空間。

0

這是一個不完整的實現,只是爲了演示這個想法:

 
class A: 
    def __init__(self, h): 
     self.h = dict(zip(map(int, h.keys()), h.values()))
def __getitem__(self, i): return self.h.get(i)
然後你可以使用這個類型來表示列表。