我正在尝试通过将列表索引作为键将dict中的所有列表转换为dict。
样本输入:
{
"checksum": "c540fcd985bf88c87e48c2bfa1df5498",
"data": {
"sampleMetrics": {
"name": "DNA Library QC Metrics",
"passQualityControl": true,
"metrics": [{
"name": "CONTAMINATION_SCORE",
"value": 1302,
"LSL": 0,
"USL": 3106,
"UOM": "NA"
}]
}
}
}
预期输出:
{
"checksum": "c540fcd985bf88c87e48c2bfa1df5498",
"data": {
"sampleMetrics": {
"name": "DNA Library QC Metrics",
"passQualityControl": true,
"metrics": {
"0": {
"name": "CONTAMINATION_SCORE"
},
"1": {
"value": 1302
},
"2": {
"LSL": 0
},
"3": {
"USL": 3106
},
"4": {
"UOM": "NA"
}
}
}
}
}
试用:
def list_to_dict_by_index(lst):
print {str(k): str(v) for k, v in enumerate(lst)}
list_to_dict_by_index([ {"d1" : 1}, {"d2" : 2} ])
但这适用于简单的列表。 如何对字典中的所有列表执行相同的操作?
(无论字典在哪里,都在列表中。)
列表可能包含另一个列表:
例如: 样本输入2 :
"metrics": [{
"name": ["CONTAMINATION_SCORE", "TOTAL_SCORE"],
"value": 1302,
"LSL": 0,
"USL": 3106,
"UOM": "NA"
}]
示例输出2 :
"metrics" : {
"0": {
"name": {
"0": "CONTAMINATION_SCORE",
"1": "TOTAL_SCORE"
}
},
"1": {
"value": 1302
},
"2": {
"LSL": 0
},
"3": {
"USL": 3106
},
"4": {
"UOM": "NA"
}
}
答案 0 :(得分:0)
dic = {
"checksum": "c540fcd985bf88c87e48c2bfa1df5498",
"data": {
"sampleMetrics": {
"name": "DNA Library QC Metrics",
"passQualityControl": True,
"metrics": [{
"name": "CONTAMINATION_SCORE",
"value": 1302,
"LSL": 0,
"USL": 3106,
"UOM": "NA"
}]
}
}
}
dic2 = dic['data']['sampleMetrics']['metrics']
dic3 ={}
for i in dic2:
for index, j in enumerate(i,0):
dic3[index]={j:i[j]}
dic['data']['sampleMetrics']['metrics'] = dic3
print(dic)
"""
output
{
'checksum': 'c540fcd985bf88c87e48c2bfa1df5498',
'data': {
'sampleMetrics': {
'name': 'DNA Library QC Metrics',
'passQualityControl': True,
'metrics': {
0: {
'name': 'CONTAMINATION_SCORE'
},
1: {
'value': 1302
},
2: {
'LSL': 0
},
3: {
'USL': 3106
},
4: {
'UOM': 'NA'
}
}
}
}
}
"""
答案 1 :(得分:0)
您的第二个示例输入/输出包含与问题标题一致的组件,即,将列表转换为以列表索引为键的字典:
# input
"name": ["CONTAMINATION_SCORE", "TOTAL_SCORE"]
# output
"name": {
"0": "CONTAMINATION_SCORE",
"1": "TOTAL_SCORE"
}
但是,两个示例输入/输出均包含字典列表,这些列表预期将以不同的方式转换,即转换为字典字典,并且将键作为字典条目的可枚举索引。
# input
"metrics": [{
...
"USL": 3106,
"UOM": "NA"
}]
# output
"metrics" : {
...
"3": {
"USL": 3106
},
"4": {
"UOM": "NA"
}
}
很多单词试图从本质上阐明以下两种情况:
{[{'foo': 'bar'}]} => {'0': {'foo': 'bar'}}
{'foo': ['bar']} => {'foo': {'0': 'bar'}}
这可能是您失败的根源。此外,您尝试解决方案仅在字典的最顶层进行迭代。如果要影响任意级别的条目,则必须递归遍历字典,即,您需要某种形式:
from collections import abv
def update(d):
for k, v in d.copy().items():
if isinstance(v, abc.Mapping):
d[k] = update(v)
else:
d[k] = iv
return d
如果您使用的是python 2而不是python 3,请使用iteritems而不是item。此外,必须进行复制,以便在对字典进行突变时不会使迭代器无效。
您可以像最初用来获取有效解决方案那样,在枚举循环中工作。小心添加递归调用以影响字典的所有级别。总的来说,这可能类似于以下内容:
from collections import abc
def list_of_dict_to_dict(d):
dd = {}
for i, (key, val) in enumerate(d.copy().items()):
dd[i] = {}
if isinstance(val, abc.Mapping):
dd[i][key] = transform_dict(val)
elif isinstance(val, list):
dd[i][key] = list_to_dict(val)
else:
dd[i][key] = val
return dd
def list_to_dict(l):
d = {}
for i, val in enumerate(l):
if isinstance(val, abc.Mapping):
d[i] = transform_dict(val)
else:
d[i] = val
return d
def transform_dict(d):
for k, v in d.copy().items():
if isinstance(v, list):
if isinstance(v[0], abc.Mapping) and len(v) == 1:
d[k] = list_of_dict_to_dict(v[0])
else:
d[k] = list_to_dict(v)
elif isinstance(v, abc.Mapping):
d[k] = transform_dict(v)
else:
d[k] = v
return d
这假定字典列表的情况始终包含单个字典。在其他情况下,您的期望还不清楚。
答案 2 :(得分:0)
您的要求很明确,但是您的第一个示例与“将列表索引作为键将dict中的所有列表转换为dict”的规则不匹配。 metrics
键映射到具有一个元素的列表,该元素是字典:[{...}]
。因此,您的预期输出是:
...
"metrics": {
"0": {
"name": "CONTAMINATION_SCORE",
"value": 1302,
"LSL": 0,
"USL": 3106,
"UOM": "NA"
}
}
...
如果这是您想要的,则只需使用DFS:
def list_to_dict_by_key(json_value):
if isinstance(json_value, list):
return {str(i):list_to_dict_by_key(v) for i,v in enumerate(json_value)}
elif isinstance(json_value, dict):
return {k:list_to_dict_by_key(v) for k,v in json_value.items()}
else:
return json_value
列表被字典替换。字典的值被处理。
>>> list_to_dict_by_key(sample1)
{'checksum': 'c540fcd985bf88c87e48c2bfa1df5498', 'data': {'sampleMetrics': {'name': 'DNA Library QC Metrics', 'passQualityControl': True, 'metrics': {'0': {'name': 'CONTAMINATION_SCORE', 'value': 1302, 'LSL': 0, 'USL': 3106, 'UOM': 'NA'}}}}}
>>> list_to_dict_by_key(sample2)
{'checksum': 'c540fcd985bf88c87e48c2bfa1df5498', 'data': {'sampleMetrics': {'name': 'DNA Library QC Metrics', 'passQualityControl': True, 'metrics': {'0': {'name': {'0': 'CONTAMINATION_SCORE', '1': 'TOTAL_SCORE'}, 'value': 1302, 'LSL': 0, 'USL': 3106, 'UOM': 'NA'}}}}}
编辑:sample1
是您的第一个样本输入,而sample2
几乎是相同的:"name": ["CONTAMINATION_SCORE", "TOTAL_SCORE"]
替换了{{ 1}}