Python如何将冒号分隔的不规则列表转换为字典
报错原因
直接调用dict()转换列表报错的核心原因是:dict()要求传入的可迭代对象中,每个元素都必须是长度恰好为2的序列——第一个元素作为字典键,第二个作为值。你传入的列表元素是未拆分的冒号分隔字符串,甚至混杂了空字符串、无冒号的无效条目,根本不符合dict()的入参要求,自然会抛出长度不匹配的错误。
实现方案
核心处理逻辑是先过滤无效条目,再将每个有效字符串按第一个冒号拆分为键、值两部分。由于你的列表中存在descr、remarks、address这类重复键,可以根据需求选择保留最后一个值,或者将同键的值汇总为列表避免数据丢失。
基础版本(重复键保留最后一个值,匹配你期望的输出结构)
raw_list = ['inetnum:1.1.1.0-1.1.1.255', 'netname:APNIC-LABS', 'descr:APNICandCloudflareDNSResolverproject', 'descr:RoutedgloballybyAS13335/Cloudflare', 'descr:ResearchprefixforAPNICLabs', 'country:AU', 'org:ORG-ARAD1-AP', 'admin-c:AR302-AP', 'tech-c:AR302-AP', 'abuse-c:AA1412-AP', 'status:ASSIGNEDPORTABLE', 'remarks:---------------', 'remarks:AllCloudflareabusereportingcanbedonevia', 'remarks:<img src="/eimg/f/5b/f5bbf78a66c792df55d04ee6bce9698d5c8accaf.png" class="email" alt="email" loading="lazy">@cloudflare.com', 'remarks:---------------', 'mnt-by:APNIC-HM', 'mnt-routes:MAINT-AU-APNIC-GM85-AP', 'mnt-irt:IRT-APNICRANDNET-AU', 'last-modified:2020-07-15T13:10:57Z', 'source:APNIC', '', 'irt:IRT-APNICRANDNET-AU', 'address:POBox3646', 'address:SouthBrisbane,QLD4101', 'address:Australia', 'e-mail:<img src="/eimg/b/11/b116938aa3180504ab727885fc8426ee57dbb10b.png" class="email" alt="email" loading="lazy">@apnic.net', 'abuse-mailbox:<img src="/eimg/b/11/b116938aa3180504ab727885fc8426ee57dbb10b.png" class="email" alt="email" loading="lazy">@apnic.net', 'admin-c:AR302-AP', 'tech-c:AR302-AP', 'auth:#Filtered', 'remarks:<img src="/eimg/b/11/b116938aa3180504ab727885fc8426ee57dbb10b.png" class="email" alt="email" loading="lazy">@apnic.netwasvalidatedon2021-02-09', 'mnt-by:MAINT-AU-APNIC-GM85-AP', 'last-modified:2021-03-09T01:10:21Z', 'source:APNIC', '', 'organisation:ORG-ARAD1-AP', 'org-name:APNICResearchandDevelopment', 'country:AU', 'address:6CordeliaSt', 'phone:+61-7-38583100', 'fax-no:+61-7-38583199', 'e-mail:<img src="/eimg/b/11/b116938aa3180504ab727885fc8426ee57dbb10b.png" class="email" alt="email" loading="lazy">@apnic.net', 'mnt-ref:APNIC-HM', 'mnt-by:APNIC-HM', 'last-modified:2017-10-11T01:28:39Z', 'source:APNIC', '', 'role:ABUSEAPNICRANDNETAU', 'address:POBox3646', 'address:SouthBrisbane,QLD4101', 'address:Australia', 'country:ZZ', 'phone:+000000000', 'e-mail:<img src="/eimg/b/11/b116938aa3180504ab727885fc8426ee57dbb10b.png" class="email" alt="email" loading="lazy">@apnic.net', 'admin-c:AR302-AP', 'tech-c:AR302-AP', 'nic-hdl:AA1412-AP', 'remarks:GeneratedfromirtobjectIRT-APNICRANDNET-AU', 'abuse-mailbox:<img src="/eimg/b/11/b116938aa3180504ab727885fc8426ee57dbb10b.png" class="email" alt="email" loading="lazy">@apnic.net', 'mnt-by:APNIC-ABUSE', 'last-modified:2021-03-09T01:10:22Z', 'source:APNIC', '', 'role:APNICRESEARCH', 'address:POBox3646', 'address:SouthBrisbane,QLD4101', 'address:Australia', 'country:AU', 'phone:+61-7-3858-3188', 'fax-no:+61-7-3858-3199', 'e-mail:<img src="/eimg/a/4a/a4a58e14449e98257260341784a655af43ebbb08.png" class="email" alt="email" loading="lazy">@apnic.net', 'nic-hdl:AR302-AP', 'tech-c:AH256-AP', 'admin-c:AH256-AP', 'mnt-by:MAINT-APNIC-AP', 'last-modified:2018-04-04T04:26:04Z', 'source:APNIC', '', '', '', 'route:1.1.1.0/24', 'origin:AS13335', 'descr:APNICResearchandDevelopment', '6CordeliaSt', 'mnt-by:MAINT-AU-APNIC-GM85-AP', 'last-modified:2018-03-16T16:58:06Z', 'source:APNIC', ''] result = {} for item in raw_list: # 跳过空字符串、不含冒号的无效条目 if not item or ':' not in item: continue # 按第一个冒号拆分,避免值中包含冒号时拆分错误 key, value = item.split(':', 1) result[key] = value
运行后result["inetnum"]对应值为1.1.1.0-1.1.1.255,result["netname"]对应值为APNIC-LABS,完全匹配你给出的期望结构。
优化版本(重复键值存为列表,不丢失数据)
如果需要保留所有重复键对应的内容,可以用如下写法:
from collections import defaultdict result = defaultdict(list) for item in raw_list: if not item or ':' not in item: continue key, value = item.split(':', 1) result[key].append(value)
此时result["descr"]会返回所有descr条目对应内容组成的列表,不会出现后续值覆盖前面值的问题。
注意事项
- 拆分字符串时必须传入
1作为split()的第二个参数,指定仅按第一个冒号拆分,避免值内容本身包含冒号(比如时间戳、URL)时被错误截断。 - 列表中混杂的空字符串、无冒号的无效条目必须提前过滤,否则会触发拆分错误。
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

