如何用Python从JSON生成企业为键、许可证到期日列表为值的字典
许可证到期信息提取问题修复
问题描述
从API获取包含许可证到期信息的JSON响应,需提取企业名称及对应的许可证到期日期列表,生成以企业名为键、到期日期列表为值的字典。当前代码能提取企业名称并创建字典,但无法正确将到期日期与对应企业关联,所有企业的到期日期列表内容完全相同。
API返回JSON示例
{ "data": [ { "id": "62525384-e0b8-4a54-9600-13e0eccf1ac2", "type": "licenses", "attributes": { "uuid": "62525384-e0b8-4a54-9600-13e0eccf1ac2", "start_time": "2018-08-24 00:00:00 +0300", "expiration_time": "2019-08-24 00:00:00 +0300", "limit_hosts": 1, "order_code": null, "comments": null, "organization_id": "07b05efa-6c5e-40d2-ab7f-348a19f02d71", "organization": { "data": { "id": "07b05efa-6c5e-40d2-ab7f-348a19f02d71", "type": "organizations", "attributes": { "uuid": "07b05efa-6c5e-40d2-ab7f-348a19f02d71", "name": "tetete", "parent_organization": 48, "company_name": "tetete", "created_at": "2018-08-24 15:24:14 +0300", "excluded_from_licenses": true } } } } }, { "id": "90f6dd88-9260-47a2-82c1-45838659e781", "type": "licenses", "attributes": { "uuid": "90f6dd88-9260-47a2-82c1-45838659e781", "start_time": "2018-08-24 14:09:38 +0300", "expiration_time": "2020-07-21 00:00:00 +0300", "limit_hosts": 0, "order_code": null, "comments": null, "organization_id": "8d9637af-fe33-48ab-b0b0-7728929c8171", "organization": { "data": { "id": "8d9637af-fe33-48ab-b0b0-7728929c8171", "type": "organizations", "attributes": { "uuid": "8d9637af-fe33-48ab-b0b0-7728929c8171", "name": "tetete", "parent_organization": 24, "company_name": "tetete", "created_at": "2018-08-24 14:09:38 +0300", "excluded_from_licenses": true } } } } } ], "meta": { "pagination": { "total_count": 133, "total_pages": 14, "per_page": 10, "current_page": 1 }, "total_licenses": 247 } }
当前问题代码
def ExtractLicenseDetails(): LicenceLibrary = dict() TempOrgList = [] for licence in lic["data"]: TempOrgList.append(licence["attributes"]["organization"]["data"]["attributes"]["name"]) LicenceLibrary = dict.fromkeys(TempOrgList, list()) # 创建字典并去重,但所有键共享同一个列表 for licence in lic["data"]: LicenceLibrary[licence["attributes"]["organization"]["data"]["attributes"]["name"]].append(licence["attributes"]["expiration_time"]) print(LicenceLibrary)
问题原因
dict.fromkeys(TempOrgList, list())会给所有字典键绑定同一个列表对象。后续往任何键对应的列表添加元素时,实际都是操作这个共享的列表,最终所有企业的到期日期列表内容完全一致。
修复方案
方案1:手动判断键是否存在,动态创建列表
遍历许可证数据时,检查企业名称是否已在字典中,不存在则创建新列表,再添加到期日期:
def ExtractLicenseDetails(): LicenceLibrary = {} for licence in lic["data"]: # 提取企业名称和到期时间 org_name = licence["attributes"]["organization"]["data"]["attributes"]["name"] exp_time = licence["attributes"]["expiration_time"] # 若企业不在字典中,初始化空列表 if org_name not in LicenceLibrary: LicenceLibrary[org_name] = [] # 添加到期时间到对应列表 LicenceLibrary[org_name].append(exp_time) print(LicenceLibrary)
方案2:使用collections.defaultdict自动初始化列表
借助defaultdict,当访问不存在的键时会自动创建指定类型的默认值(这里是列表):
from collections import defaultdict def ExtractLicenseDetails(): LicenceLibrary = defaultdict(list) for licence in lic["data"]: org_name = licence["attributes"]["organization"]["data"]["attributes"]["name"] exp_time = licence["attributes"]["expiration_time"] LicenceLibrary[org_name].append(exp_time) # 如需转为普通字典,可使用dict()转换 print(dict(LicenceLibrary))
内容的提问来源于stack exchange,提问作者Corvus Corax
相关产品推荐
相关产品推荐

