[英]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.