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

Python zip()创建字典仅含2条记录而非千余条的问题排查

列表zip转字典仅返回2条记录的异常排查与修复

问题场景

完成Codecademy平台美国医疗保险成本组合项目时,创建smoking_status、insurance_costs两个列表存储CSV中读取的吸烟状态、保险成本字段,用于分析两类人群的成本差异。通过zip()打包两个列表、用字典推导式生成字典时,最终输出仅包含2个键值对,对应CSV文件最后两条数据,未得到预期的1000余条记录。
涉及的原始代码:

import csv

insurance_db = 

with open('insurance.csv',newline='') as insurance_csv:
    insurance_reader = csv.DictReader(insurance_csv)
    for row in insurance_reader:
        insurance_db.append(row)

smoking_status = []

for person in insurance_db:
    smoking_status.append(person.get('smoker'))

insurance_costs = []

for person in insurance_db:
    insurance_costs.append(person.get('charges'))

smoker_dictionary = {key:value for key,value in zip(smoking_status,insurance_costs)}

print(smoker_dictionary)

实际运行输出:

{'yes': '29141.3603', 'no': '2007.945'}

异常成因

核心原因是Python字典的键具有全局唯一性,同键重复赋值时新值会直接覆盖旧值:

  • smoking_status列表的取值只有'yes'、'no'两类,不存在其他值
  • 字典推导式遍历zip生成的键值对时,每遍历到一条吸烟状态为'yes'的记录,就会覆盖字典中已有的'yes'键对应的值;'no'键同理
  • 遍历完全部1000余条记录后,两个键各自仅保留最后一次被赋值的内容,正好对应CSV文件末尾两条记录的数值。
    另外原始代码存在显性语法问题:insurance_db = 后未初始化空列表,运行时会直接触发NameError,需要补全为insurance_db = []。

修复方案

根据实际业务需求选择对应写法即可:

  • 需求1:按吸烟状态分组,统计两类人群的成本特征(如平均成本、成本区间)
    不要直接用吸烟状态作为单值键,改为将同状态的所有成本存入键对应的列表中,参考代码:
    import csv
    
    insurance_db = []
    
    with open('insurance.csv', newline='') as insurance_csv:
        insurance_reader = csv.DictReader(insurance_csv)
        for row in insurance_reader:
            insurance_db.append(row)
    
    # 初始化分组字典,键为吸烟状态,值为对应人群的所有成本
    smoker_cost_dict = {'yes': [], 'no': []}
    for person in insurance_db:
        smoker_status = person.get('smoker')
        # 把成本转成浮点数,方便后续做数值计算
        charge = float(person.get('charges'))
        smoker_cost_dict[smoker_status].append(charge)
    
    # 后续可直接做统计计算,比如计算两类人群的平均保险成本
    avg_smoker_cost = sum(smoker_cost_dict['yes']) / len(smoker_cost_dict['yes'])
    avg_non_smoker_cost = sum(smoker_cost_dict['no']) / len(smoker_cost_dict['no'])
    
  • 需求2:存储所有记录的映射关系
    不要用重复度极高的吸烟状态作为字典键,改用每条记录的唯一标识(如记录序号、用户ID)作为键,值存储包含吸烟状态、保险成本的结构化数据,避免键重复覆盖。

原始字典推导式的逻辑等价于逐行给字典同键重复赋值,执行过程可以通过以下代码直观复现:

test_dict = {}
# 模拟遍历前1000条重复yes/no的记录
for i in range(1000):
    if i % 2 == 0:
        test_dict['yes'] = i
    else:
        test_dict['no'] = i
# 最终输出只会保留最后一次赋值的998、999两个值
print(test_dict)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:09:20