簡體   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