使用os.walk遍历CSV文件时重复打印结果的原因排查
问题:处理目录下CSV文件时重复打印统计结果
代码可正常完成文件读写与内容处理,但控制台会重复输出相同的统计结果(比如预期打印2行,实际输出4行),代码及打印结果如下:
import os import csv root_directory = '.' for subdir, dirs, files in os.walk(root_directory): for file in files: if file.endswith('.csv'): initial = {} repeated = set() my_file = file sample = my_file[:2] output_file = '{}_result.txt'.format(sample.lower()) with open(my_file, mode='r') as in_file, \ open(output_file, mode='w') as out_file: next(in_file) reader = csv.reader(in_file, delimiter="\t") for i, line in enumerate(reader): row = line[0].split(',') if row[1] in initial: shouldAdd = initial[row[1]] != row[2] if shouldAdd: repeated.add(row[1]) out_file.write('{}\n'.format(row[1])) # writing to file here no issues, no duplicates else: initial[row[1]] = row[2] #Issue is here. Why printing twice print('Total repeats for {} sample: {}'.format(sample, len(repeated)))
打印结果:
Total repeats for AA sample: 123 Total repeats for BB sample: 45 Total repeats for AA sample: 123 Total repeats for BB sample: 45
重复打印的原因
核心问题是代码对每个同前缀的CSV文件单独统计并即时打印:
- 你的逻辑是遍历到一个CSV文件,就单独处理它、计算该文件内的重复项,处理完立刻打印对应样本(文件名前两位)的统计结果。
- 如果目录下存在多个同前缀的CSV文件(比如
AA_01.csv和AA_02.csv),每个文件都会触发一次打印,自然就会出现重复的输出内容。
额外隐藏问题
代码还存在路径处理漏洞:os.walk返回的file只是单纯的文件名,不是完整路径。如果子目录下有CSV文件,直接open(file)会找不到文件(当前工作目录是根目录,而非子目录),正确的做法是用os.path.join(subdir, file)拼接出完整文件路径。
解决思路
如果需要同一样本只打印一次统计结果,得先合并同前缀所有文件的重复项,再统一打印:
- 导入
from collections import defaultdict,初始化全局字典sample_repeats = defaultdict(set),用来存储每个样本的重复集合。 - 遍历CSV文件时,把当前文件的重复项添加到对应样本的集合中,不要急于打印。
- 所有文件处理完成后,遍历
sample_repeats字典,逐个打印每个样本的统计结果。
内容的提问来源于stack exchange,提问作者karvai
相关产品推荐
相关产品推荐

