Python if循环比较相邻值时+0.35增量判新零件条件未正常执行
问题背景
需要遍历从DataFrame提取的位置值列表,按规则为每个位置值分配零件编号,写入目标CSV文件的对应列。
示例位置列表:
[0.3, 0.3, 0.5, 0.5, 0.3, 0.65, 0.65, 0.65, 1.2, 1.0, 1.0, 1.0]
判定规则:
- 相邻值增量为+0.35或+0.55时,判定为新零件,零件编号递增
- 相邻值差值在±0.2范围内(含两值相等)时,判定为同一零件,编号保持不变
- 最终编号格式为
Part1、Part2、Part3……依次顺延
运行自行编写的脚本时出现异常:判定+0.35增量触发新零件、编号递增的逻辑未生效,其余条件可正常执行,+0.35增量场景下零件编号未按预期递增。
原实现代码如下:
import pandas as pd import csv new_df = pd.read_csv("new_df.csv") col_list = new_df['builder'].tolist() with open('part.csv', 'w', newline='') as layer_csv: writer = csv.writer(layer_csv) writer.writerow(["position","Part"]) n=0 for i in range(len(col_list) -1): part_check = col_list[i] + 0.35 part_check2 = col_list[i] + 0.55 part_check3 = col_list[i] - 0.2 part_check4 = col_list[i] + 0.2 if col_list[i] == col_list[i+1]: writer.writerow([col_list[i],"Part" + "" + str(n)]) if col_list[i] + 0.35 == col_list[i+1]: n+=1 writer.writerow([col_list[i],"Part" + "" + str(n)]) elif col_list[i] + 0.55 == col_list[i+1]: writer.writerow([col_list[i],"Part" + "" + str(n)]) n+=1 elif col_list[i] - 0.20 == col_list[i+1] or col_list[i] + 0.20 == col_list[i+1]: writer.writerow([col_list[i],"Part" + "" + str(n)])
故障原因
- 浮点数精度误差:Python中浮点数基于二进制存储,计算存在精度偏差,比如
0.3 + 0.35的实际计算结果为0.6500000000000001,直接用==和列表中存储的0.65做相等判断会返回False,这是+0.35判定逻辑失效的核心原因。 - 分支逻辑错误:判断两值相等的
if语句是独立分支,未和后续的if/elif逻辑串联,会触发重复写入行的问题;±0.2范围的判定仅判断了差值刚好等于±0.2的场景,未覆盖区间内所有差值情况。 - 边界处理错误:循环遍历范围为
range(len(col_list)-1),列表最后一个元素不会被写入CSV;初始编号n=0,第一个零件会被标记为Part0,不符合从1开始编号的要求。
修复方案
- 引入极小容差值做浮点数相等判断,规避精度误差
- 重构分支逻辑,从第二个元素开始遍历,通过当前值和前一个值的差值判定零件归属,避免重复写入
- 修正初始编号值,补全最后一个元素的写入逻辑
- 将±0.2范围判定改为差值绝对值判断,覆盖所有同零件场景
修复后可直接运行的代码:
import pandas as pd import csv new_df = pd.read_csv("new_df.csv") col_list = new_df['builder'].tolist() # 浮点数判定容差,解决精度问题 FLOAT_TOL = 1e-9 with open('part.csv', 'w', newline='') as layer_csv: writer = csv.writer(layer_csv) writer.writerow(["position", "Part"]) # 零件编号从1开始计数 part_num = 1 # 写入第一个位置的记录 writer.writerow([col_list[0], f"Part{part_num}"]) for i in range(1, len(col_list)): prev_val = col_list[i-1] curr_val = col_list[i] val_diff = curr_val - prev_val # 增量符合新零件规则时,编号递增 if abs(val_diff - 0.35) < FLOAT_TOL or abs(val_diff - 0.55) < FLOAT_TOL: part_num += 1 # 差值超出±0.2范围的异常值可在此处加自定义处理逻辑,默认暂归为当前零件 # 写入当前位置记录 writer.writerow([curr_val, f"Part{part_num}"])
针对给出的示例列表,修复后代码的输出完全符合预期:0.3到0.65的+0.35增量会正确触发编号递增为Part2,0.65到1.2的+0.55增量会正确触发编号递增为Part3,其余同零件场景编号保持不变。
内容的提问来源于stack exchange,提问作者devman3211
相关产品推荐
相关产品推荐

