在python中将列表索引作为键将dict中的所有列表转换为dict

2024-05-29 04:33:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在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} ])

但这适用于简单列表。如何对dict中的所有列表执行相同的操作?

(无论字典里有什么单子)

列表可能包含另一个列表:

例如: 样本输入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"
    }
}

Tags: name列表datavalueusldictmetricsscore
3条回答

第二个示例输入/输出包含与问题标题一致的组件,即将列表转换为以列表索引为键的字典:

# 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"
    }
}

这是许多试图表达以下两种情况的词语:

  1. {[{'foo': 'bar'}]} => {'0': {'foo': 'bar'}}
  2. {'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

如果您使用的是Python2而不是Python3,请使用iteritems而不是items。此外,复制是必要的,这样迭代器就不会在字典发生变化时失效。你知道吗

您可以在枚举循环中工作,就像您最初用来获得工作解决方案一样。小心添加递归调用以影响字典的所有级别。总的来说,这可能类似于以下内容:

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

这假设字典列表大小写总是包含一个字典。不清楚你在其他情况下会期望什么。你知道吗

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

你要问的很清楚,但是你的第一个例子不符合规则“通过将列表索引作为键将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"]替换"name": "CONTAMINATION_SCORE"

相关问题 更多 >

    热门问题