繁体   English   中英

将列表转换为嵌套列表和dicts

[英]Convert list to nested lists and dicts

我有一组看起来类似的数据:

[  {"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"}
]

名称从包含列表和dicts的嵌套数据中展平。 我现在想把它放回到dicts和list(在适当的地方)。

到目前为止我有这个:

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'}
}

但是现在,我希望任何具有可以全部转换为int的键的dict转换为列表,所以我的最终输出看起来更像:

{'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'}
}

有关如何实现这一目标的任何建议?

这可能不是最有效的方法,但......

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'}}

您可以更改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字典有你想要的内容

您可以递归遍历所有字典,并检查是否可以使用以下所有键转换为整数:

map(int, your_dict.keys())

如果其中一个键无法转换为int则会生成ValueError

请注意,这不会检查键是否是连续的整数,也不会检查它们是否从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)
然后您可以使用此类型来表示列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM