Python,重组字典数组

时间:2019-02-21 15:31:48

标签: python

说实话,对于我来说用JS或Perl制作起来太容易了,但是由于使用复杂的工具来处理字典/列表,所以我完全坚持使用Python。所以,我需要什么:

我有一系列的字典:

[
    {"id": 1, "name": "Res1", "type": "resource", "k_name": "Ind1_1", "k_id": 4},
    {"id": 1, "name": "Res1", "type": "resource", "k_name": "Ind1_2", "k_id": 5},
    {"id": 1, "name": "Res1", "type": "resource", "k_name": "Ind1_3", "k_id": 6},
    {"id": 2, "name": "Res2", "type": "service", "k_name": "Ind2_1", "k_id": 7},
    {"id": 2, "name": "Res2", "type": "service", "k_name": "Ind2_2", "k_id": 8},
    {"id": 2, "name": "Res2", "type": "service", "k_name": "Ind2_3", "k_id": 9},
    {"id": 2, "name": "Res2", "type": "service", "k_name": "Ind2_4", "k_id": 10},
    {"id": 3, "name": "Res3", "type": "service", "k_name": "Ind3_1", "k_id": 11},
    {"id": 3, "name": "Res3", "type": "service", "k_name": "Ind3_2", "k_id": 12},
    {"id": 3, "name": "Res3", "type": "service", "k_name": "Ind3_3", "k_id": 13},
    {"id": 3, "name": "Res3", "type": "service", "k_name": "Ind3_4", "k_id": 14}
]

我需要做到这一点:

[
    {
        "id": 1,
        "name": "Res1",
        "type": "resource",
        "indicators": [
            {"name": "Ind1_1","id": 4},
            {"name": "Ind1_2","id": 5},
            {"name": "Ind1_3","id": 6}
        ]
    },
    {
        "id": 2,
        "name": "Res2",
        "type": "service",
        "indicators": [
            {"name": "Ind2_1","id": 7},
            {"name": "Ind2_2","id": 8},
            {"name": "Ind2_3","id": 9},
            {"name": "Ind2_4","id": 10}
        ]
    },
    {
        "id": 3,
        "name": "Res3",
        "type": "service",
        "indicators": [
            {"name": "Ind3_1","id": 11},
            {"name": "Ind3_2","id": 12},
            {"name": "Ind3_3","id": 13},
            {"name": "Ind3_4","id": 14}
        ]
    }
]

你能帮我吗?

2 个答案:

答案 0 :(得分:2)

string url = string.Empty; string title = string.Empty; int cw = 1, ct = 1; //current window, current tab in the current window Rootobject root = JsonConvert.DeserializeObject<Rootobject>(textBox1.Text); MessageBox.Show("Test"); textBox1.Clear(); foreach (var w in root.windows) { foreach (var t in w.tabs[0].formdata.id.sessionData.windows[0].tabs) { url = t.entries[0].url; title = t.entries[0].title; textBox1.Text += cw.ToString() + " - " + ct.ToString() + " - " + url + " - " + title + Environment.NewLine; ct++; } cw++; } 进行救援:

itertools

import itertools # Assuming your original list is `l` # if it does not come in order, you need to do this line first, and will probably be less efficient. l = sorted(l, key=lambda x:(x["id"], x["name"], x["type"])) d = [] for k, g in itertools.groupby(l, lambda x: (x["id"], x["name"], x["type"])): d.append({i:v for i, v in zip(["id", "name", "type"], k)}) d[-1]["indicator"] = [{y.split('_')[1]:e[y] for y in ["k_id", "k_name"]} for e in list(g)] 变为:

d

答案 1 :(得分:1)

您可以使用映射字典将id映射到相应的子列表,以便遍历列表(在本示例中为l)时,可以将新条目附加到如果在映射中找不到id,则输出列表;如果在映射中找到id,则将条目追加到现有子列表中:

mapping = {}
output = []
for d in l:
    i = {'name': d.pop('k_name'), 'id': d.pop('k_id')}
    if d['id'] in mapping:
        mapping[d['id']].append(i)
    else:
        output.append({**d, 'indicators': [i]})
        mapping[d['id']] = output[-1]['indicators']

output变为:

[{'id': 1, 'name': 'Res1', 'type': 'resource', 'indicators': [{'name': 'Ind1_1', 'id': 4}, {'name': 'Ind1_2', 'id': 5}, {'name': 'Ind1_3', 'id': 6}]}, {'id': 2, 'name': 'Res2', 'type': 'service', 'indicators': [{'name': 'Ind2_1', 'id': 7}, {'name': 'Ind2_2', 'id': 8}, {'name': 'Ind2_3', 'id': 9}, {'name': 'Ind2_4', 'id': 10}]}, {'id': 3, 'name': 'Res3', 'type': 'service', 'indicators': [{'name': 'Ind3_1', 'id': 11}, {'name': 'Ind3_2', 'id': 12}, {'name': 'Ind3_3', 'id': 13}, {'name': 'Ind3_4', 'id': 14}]}]