2011-10-10 102 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)
然后你可以使用这个类型来表示列表。