如何在Python中对字典列表进行分组?

ris*_*ant 5 python

我是Python的新手。我有一个字典列表,如下所示

[
    {
        'key1': 'value1',
        'key2': [
            {
                'id': 1,
                'name': 'name1'
            },
            {
                'id': 2,
                'name': 'name2'
            },
            {
                'id': 3,
                'name': 'name3'
            }
        ]
    },
    {
        'key1': 'value1',
        'key2': [
            {
                'id': 1,
                'name': 'name1'
            },
        ]
    },
    {
        'key1': 'value1',
        'key2': [
            {
                'id': 1,
                'name': 'name1'
            },
        ]
    }
]
Run Code Online (Sandbox Code Playgroud)

我想将此列表转换为基于通用key2-id的列表列表,结果列表看起来像

[
    [
        {
            'key1': 'value1',
            'key2': [
                {'id': 2, 'name': 'name2'},
                {'id': 3, 'name': 'name3'}]}
    ],
    [
        {
            'key1': 'value1',
            'key2': [{'id': 1, 'name': 'name1'}]
        },
        {
            'key1': 'value1',
            'key2': [{'id': 1, 'name': 'name1'}]
        },
        {
            'key1': 'value1',
            'key2': [{'id': 1, 'name': 'name1'}]}
    ]
]
Run Code Online (Sandbox Code Playgroud)

我尝试使用gropbyitertool 来完成此操作,如下所示:

from itertools import groupby
def _group_by_key2_ids(results):
    groupby_iterator = groupby(
        results,
        lambda x: [item.get('id') for item in x.get('key2')]
    )
    return [list(x) for _, x in groupby_iterator]
Run Code Online (Sandbox Code Playgroud)

它没有给出我想要的结果。它的输出看起来像

[
    [
        {
            'key1': 'value1',
            'key2': [
                {'id': 1, 'name': 'name1'},
                {'id': 2, 'name': 'name2'},
                {'id': 3, 'name': 'name3'}]}
    ],
    [
        {
            'key1': 'value1',
            'key2': [{'id': 1, 'name': 'name1'}]
        },
        {
            'key1': 'value1',
            'key2': [{'id': 1, 'name': 'name1'}]}]
]
Run Code Online (Sandbox Code Playgroud)

请让我知道,我们如何做到这一点。任何帮助,将不胜感激。谢谢。

Aja*_*234 1

您可以展平数据并应用itertools.groupby

import itertools
data = [{'key1': 'value1', 'key2': [{'id': 1, 'name': 'name1'}, {'id': 2, 'name': 'name2'}, {'id': 3, 'name': 'name3'}]}, {'key1': 'value1', 'key2': [{'id': 1, 'name': 'name1'}]}, {'key1': 'value1', 'key2': [{'id': 1, 'name': 'name1'}]}]
new_d = sorted([(i, a['key1']) for a in data for i in a['key2']], key=lambda x:x[0]['id'])
result = [[{'key1':d, 'key2':c} for c, d in b] for a, b in itertools.groupby(new_d, key=lambda x:x[0]['id'])]
Run Code Online (Sandbox Code Playgroud)
import json
print(json.dumps(result, indent=4))
Run Code Online (Sandbox Code Playgroud)

输出:

[
  [
    {
        "key1": "value1",
        "key2": {
            "id": 1,
            "name": "name1"
        }
    },
    {
        "key1": "value1",
        "key2": {
            "id": 1,
            "name": "name1"
        }
    },
    {
        "key1": "value1",
        "key2": {
            "id": 1,
            "name": "name1"
        }
    }
 ],
 [
    {
        "key1": "value1",
        "key2": {
            "id": 2,
            "name": "name2"
        }
     }
  ],
  [
    {
        "key1": "value1",
        "key2": {
            "id": 3,
            "name": "name3"
        }
     }
   ]
]
Run Code Online (Sandbox Code Playgroud)