为何触发ZeroDivisionError?Python CSV计算GROWTH字段报错求助
解决CSV处理中的ZeroDivisionError与逻辑问题
嘿,我来帮你搞定这个问题!首先咱们先拆解你遇到的错误和代码里的核心问题:
直接错误原因:ZeroDivisionError
你看到的ZeroDivisionError是因为当x['MID']的值是'0'时,float(x['MID'])会转换成0.0,执行-0.0 / 0.0就触发了除以零的错误。而这个情况之所以会进入第一个if分支,是因为你的条件判断逻辑写得有问题。
核心问题:条件判断的语法与逻辑错误
你的第一个if条件x['MID'] != '' or '0'完全不符合预期!Python里的逻辑判断不能像自然语言那样简写:
- 这个表达式等价于
(x['MID'] != '') or bool('0'),而非空字符串在布尔判断中是True,所以bool('0')永远为True,导致这个if条件永远成立,所有行都会进入第一个分支,包括MID为'0'的行,自然就触发了除以零的错误。 - 另外,你的条件里
and和or的优先级也有问题,x['MID'] != '' or '0' and x['REP'] == ''会被解析成(x['MID'] != '') or ('0' and x['REP'] == ''),这也不是你想要的逻辑。
排查思路&修正步骤
1. 先明确GROWTH的计算规则
根据你的输入数据和期望输出,我们可以整理出清晰的规则:
- 空字段视为
0(比如MID或REP为空时,当作0处理) - 当MID为0时:
- 如果REP也为0 → GROWTH = 0
- 如果REP不为0 → GROWTH =
inf(或-inf,根据REP正负,你的示例里用inf)
- 当MID不为0时:
- 如果REP为空(视为0)→ GROWTH = (0 - MID)/MID = -1
- 如果REP不为空 → GROWTH = (REP - MID)/MID
2. 修正后的代码
我重新写了一份更清晰、健壮的代码,解决了你的问题:
import csv # 把计算GROWTH的逻辑封装成函数,方便调试和维护 def calculate_growth(mid_str, rep_str): # 处理空字符串,转为'0';同时去除前后空格 mid_clean = mid_str.strip() or '0' rep_clean = rep_str.strip() or '0' # 处理非数字的异常情况(比如字段是字符串) try: mid = float(mid_clean) rep = float(rep_clean) except ValueError: mid = 0.0 rep = 0.0 # 按规则计算GROWTH if mid == 0.0: if rep == 0.0: return 0.0 else: # 根据REP正负返回正无穷或负无穷,你示例里用inf,这里可以调整 return float('inf') if rep > 0 else float('-inf') else: return (rep - mid) / mid # 读取输入文件并处理 with open('input.csv', 'r', newline='') as input_file: reader = csv.DictReader(input_file) output_rows = [] for row in reader: # 计算当前行的GROWTH growth_val = calculate_growth(row['MID'], row['REP']) # 构造输出行,只保留需要的字段 output_row = { 'NEPTUN': row['NEPTUN'], 'GROWTH': growth_val } output_rows.append(output_row) # 写入输出文件 with open('output.csv', 'w', newline='') as output_file: fieldnames = ['NEPTUN', 'GROWTH'] writer = csv.DictWriter(output_file, fieldnames=fieldnames) writer.writeheader() writer.writerows(output_rows)
3. 代码的改进点
- 用函数封装计算逻辑,更清晰,方便后续修改规则
- 自动处理空字符串和非数字字段,避免
ValueError - 明确判断MID为0的情况,彻底避免
ZeroDivisionError - 使用
with语句自动管理文件,不需要手动调用close() - 直接构造输出行,不需要维护两个独立列表,逻辑更简洁
验证结果
用你的输入数据测试,这个代码会生成符合你期望的输出,比如:
BQ6IAJ对应的GROWTH是(9-19)/19 ≈ -0.5263,和你的示例一致BWQ5AU对应的MID为空(视为0),REP为1,所以GROWTH是inf,和示例一致RQQCFE对应的MID为空(视为0),REP为0,所以GROWTH是0,和示例一致
内容的提问来源于stack exchange,提问作者JKM
相关产品推荐
相关产品推荐

