Python编写CSV遇重复行问题:特定条件下避免重复写入求助
解决CSV筛选去重的逻辑问题
我来帮你梳理下代码里的核心问题,然后给出可行的解决方案:
原代码的几个关键问题
- 文件上下文管理错误:你把
csv_reader放在单独的with块里,当这个块结束时,原CSV文件就被关闭了,后续遍历csv_reader会直接报错(迭代器已失效)。必须把读写操作放在同一个或嵌套的with块中,保证原文件在读取时始终处于打开状态。 - 错误的重复检查方式:试图遍历写模式的
new_file来判断重复是行不通的——写模式下无法读取文件内容,就算能读,读出来的是字符串行,也不能直接用字典字段的方式访问。 - 去重核心逻辑缺失:没有记录已经写入过的、需要去重的SKU,根本无法判断当前行是否重复。
修正后的解决方案
核心思路是用集合存储已处理的SKU(针对SKU非空且PART_STOCKING_FLAG为Y的行),每次遇到这类行时先检查SKU是否在集合中,不存在才写入并加入集合。同时调整文件操作结构,保证逻辑清晰:
import csv # 嵌套with块,确保两个文件都在正确的上下文环境中 with open('4-22 inventory.csv', 'r') as csv_file, open('stocking.csv', 'w', newline='') as new_file: csv_reader = csv.DictReader(csv_file) fieldnames = ['SEGMENT_CODE','WHS_NUMBER','WHS_GL_NUMBER', 'LINE_CODE', 'SUBLINE_CODE', 'PART_NBR', 'SKU_NUMBER', 'MASTER_ITEM_FLAG', 'PART_STOCKING_FLAG', 'PART_STATUS_CODE', 'PART_MOVEMENT_CODE', 'SUB_MOVEMENT_CODE', 'FULL_MOVEMENT_CODE', 'FACTORY_PACK_QTY', 'OH_UNIT_QTY', 'ON_ORDER_UNIT_QTY', 'UNIT_COST'] csv_writer = csv.DictWriter(new_file, fieldnames=fieldnames) csv_writer.writeheader() # 用集合记录已写入的需要去重的SKU,集合查询效率远高于列表 seen_skus = set() for line in csv_reader: # 提前提取关键字段,简化后续判断 whs_number = line['WHS_NUMBER'] stocking_flag = line['PART_STOCKING_FLAG'] sku = line['SKU_NUMBER'].strip() # 去除首尾空格,避免因空格导致的假重复 # 情况1:WHS为NCI且库存标记为Y,直接写入 if whs_number == 'NCI' and stocking_flag == 'Y': csv_writer.writerow(line) # 情况2:非NCI、SKU非空且库存标记为Y,检查是否重复 elif whs_number != 'NCI' and sku and stocking_flag == 'Y': if sku not in seen_skus: seen_skus.add(sku) csv_writer.writerow(line) # 已存在则跳过,无需额外操作 # 其他情况:直接写入 else: csv_writer.writerow(line)
代码关键点说明
- 嵌套with块:保证原CSV文件在整个读取过程中保持打开,避免迭代器失效问题。
seen_skus集合:集合的查询操作是O(1)时间复杂度,比用列表存储并遍历检查高效得多。- SKU预处理:用
strip()去除SKU的首尾空格,避免类似'ABC123 '和'ABC123'被误判为不同SKU的情况。 - 清晰的条件分支:把三种处理逻辑拆分开,避免原代码中
elif后写True再continue的冗余写法,逻辑更易读维护。
内容的提问来源于stack exchange,提问作者Jonathan Fitzpatrick
相关产品推荐
相关产品推荐

