You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python如何将字典列表按UserName分组为嵌套字典结构

问题描述

现有如下字典列表:

[
    {'UserName': 'aaa', 'AccessKeyId': 'AKIAYWQTISJD6X27YVK', 'Status': 'Active', 'CreateDate': datetime.datetime(2022, 9, 8, 15, 56, 39, tzinfo=tzutc())},
    {'UserName': 'eee', 'AccessKeyId': 'AKIAYWQTISJD6QXMAKY', 'Status': 'Active', 'CreateDate': datetime.datetime(2023, 1, 24, 12, 30, 59, tzinfo=tzutc())}, 
    {'UserName': 'eee', 'AccessKeyId': 'AKIAYWQTISJDUARK6FV', 'Status': 'Active', 'CreateDate': datetime.datetime(2023, 1, 24, 16, 58, 38, tzinfo=tzutc())}
]

需要转换为以UserName为键、对应值为该用户相关字典(移除UserName字段)列表的嵌套字典:

{
  "aaa": [
    {'AccessKeyId': 'AKIAYWQTISJD6X27YVK', 'Status': 'Active', 'CreateDate': datetime.datetime(2022, 9, 8, 15, 56, 39, tzinfo=tzutc())}],
  "eee": [
    {'AccessKeyId': 'AKIAYWQTISJD6QXMAKY', 'Status': 'Active', 'CreateDate': datetime.datetime(2023, 1, 24, 12, 30, 59, tzinfo=tzutc())}, 
    {'AccessKeyId': 'AKIAYWQTISJDUARK6FV', 'Status': 'Active', 'CreateDate': datetime.datetime(2023, 1, 24, 16, 58, 38, tzinfo=tzutc())}
   ]
}

尝试了以下代码,但同一用户的多条数据仅能保留最后一条,无法生成列表:

import copy

list_per_user = {i['UserName']: copy.deepcopy(i) for i in key_list} 
for obj in list_per_user:     
   del list_per_user[obj]['UserName'] 
解决方案

问题出在字典推导式的特性:当键重复时,后面的键值对会覆盖前面的,所以同一用户的多条记录最后只留下了最后一条。要实现需求,需要为每个用户维护一个列表,把对应记录添加进去。

方法一:普通循环实现

from datetime import datetime, timezone
import copy

key_list = [
    {'UserName': 'aaa', 'AccessKeyId': 'AKIAYWQTISJD6X27YVK', 'Status': 'Active', 'CreateDate': datetime(2022, 9, 8, 15, 56, 39, tzinfo=timezone.utc)},
    {'UserName': 'eee', 'AccessKeyId': 'AKIAYWQTISJD6QXMAKY', 'Status': 'Active', 'CreateDate': datetime(2023, 1, 24, 12, 30, 59, tzinfo=timezone.utc)}, 
    {'UserName': 'eee', 'AccessKeyId': 'AKIAYWQTISJDUARK6FV', 'Status': 'Active', 'CreateDate': datetime(2023, 1, 24, 16, 58, 38, tzinfo=timezone.utc)}
]

result = {}
for item in key_list:
    username = item['UserName']
    # 深拷贝原字典并移除UserName字段
    user_data = copy.deepcopy(item)
    del user_data['UserName']
    # 如果用户已在结果中,追加数据;否则创建新列表
    if username in result:
        result[username].append(user_data)
    else:
        result[username] = [user_data]

print(result)

方法二:使用collections.defaultdict简化代码

defaultdict可以自动为不存在的键生成默认值(这里是空列表),让代码更简洁:

from datetime import datetime, timezone
import copy
from collections import defaultdict

key_list = [
    {'UserName': 'aaa', 'AccessKeyId': 'AKIAYWQTISJD6X27YVK', 'Status': 'Active', 'CreateDate': datetime(2022, 9, 8, 15, 56, 39, tzinfo=timezone.utc)},
    {'UserName': 'eee', 'AccessKeyId': 'AKIAYWQTISJD6QXMAKY', 'Status': 'Active', 'CreateDate': datetime(2023, 1, 24, 12, 30, 59, tzinfo=timezone.utc)}, 
    {'UserName': 'eee', 'AccessKeyId': 'AKIAYWQTISJDUARK6FV', 'Status': 'Active', 'CreateDate': datetime(2023, 1, 24, 16, 58, 38, tzinfo=timezone.utc)}
]

result = defaultdict(list)
for item in key_list:
    user_data = copy.deepcopy(item)
    del user_data['UserName']
    result[item['UserName']].append(user_data)

# 如果需要转为普通字典,可执行:result = dict(result)
print(result)

方法三:不使用深拷贝(如果原数据不需要保留)

如果不需要保留原列表中的字典,可以直接修改原字典(注意这会改变原数据),省去深拷贝的开销:

from datetime import datetime, timezone
from collections import defaultdict

key_list = [
    {'UserName': 'aaa', 'AccessKeyId': 'AKIAYWQTISJD6X27YVK', 'Status': 'Active', 'CreateDate': datetime(2022, 9, 8, 15, 56, 39, tzinfo=timezone.utc)},
    {'UserName': 'eee', 'AccessKeyId': 'AKIAYWQTISJD6QXMAKY', 'Status': 'Active', 'CreateDate': datetime(2023, 1, 24, 12, 30, 59, tzinfo=timezone.utc)}, 
    {'UserName': 'eee', 'AccessKeyId': 'AKIAYWQTISJDUARK6FV', 'Status': 'Active', 'CreateDate': datetime(2023, 1, 24, 16, 58, 38, tzinfo=timezone.utc)}
]

result = defaultdict(list)
for item in key_list:
    username = item.pop('UserName')
    result[username].append(item)

print(result)

内容的提问来源于stack exchange,提问作者opti2k4

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 22:16:17