Python识别主文件夹及子文件夹重复PDF文件的代码逻辑排查
PDF文件去重代码逻辑问题排查
我是Python新手,正在学习Python。需要识别主文件夹xx及其子文件夹yy中的唯一PDF文件,重复文件可能具有不同文件名(示例:filename1.pdf与filename1_23.pdf为重复文件),期望输出保留首次出现的唯一文件列表。现有代码可运行但无法正确识别唯一文件,请求帮忙排查代码逻辑问题。
原代码如下:
import os import fitz path = 'E:/username/Desktop/xx' pdf_paths = [os.path.join(root, name) for root, dirs, files in os.walk(path) for name in files if name.endswith('.pdf')] def extract_text_from_pdf(pdf_path): text = '' pdf_document = fitz.open(pdf_path) for page_num in range(pdf_document.page_count): page = pdf_document.load_page(page_num) text += page.get_text() pdf_document.close() return text def compare_pdfs(pdf_path1, pdf_path2): text1 = extract_text_from_pdf(pdf_path1) text2 = extract_text_from_pdf(pdf_path2) if text1==text2: return True else: return False def compare_multiple_pdfs(pdf_paths): unique_files = [] for i in range(len(pdf_paths)): for j in range(i+1, len(pdf_paths)): pdf_path1 = pdf_paths[i] pdf_path2 = pdf_paths[j] if compare_pdfs(pdf_path1, pdf_path2): for existing_file in unique_files: if compare_pdfs(pdf_path1, existing_file): break else: unique_files.append(pdf_path1) else: for existing_file in unique_files: if compare_pdfs(pdf_path1, existing_file) and compare_pdfs(pdf_path2, existing_file): break elif compare_pdfs(pdf_path1, existing_file): unique_files.append(pdf_path2) elif compare_pdfs(pdf_path2, existing_file): unique_files.append(pdf_path1) else: unique_files.append(pdf_path1) unique_files.append(pdf_path2) return unique_files compare_multiple_pdfs(pdf_paths)
原代码的核心问题
- 缩进错误:内层
for j循环的代码块没有缩进,导致每次外层for i循环只会拿到最后一个j对应的文件,完全没实现两两比较的逻辑。 - 提前返回:
return unique_files放在外层for i循环内部,第一次循环就直接返回,根本没处理所有PDF文件。 - 逻辑混乱:去重逻辑绕了弯路,没有遵循“首次出现保留”的简单思路,反而用复杂的两两比较判断,容易出现重复添加或遗漏的情况。
- 效率低下:每次比较都重复提取PDF文本,同一文件的文本会被多次提取,浪费资源。
修正后的代码
改用“缓存文本+遍历判断”的思路,保证首次出现的文件被保留,同时提升效率:
import os import fitz path = 'E:/username/Desktop/xx' # 遍历所有子文件夹获取PDF路径,os.walk的顺序保证首次出现的文件排在前面 pdf_paths = [os.path.join(root, name) for root, dirs, files in os.walk(path) for name in files if name.endswith('.pdf')] def extract_text_from_pdf(pdf_path): text = '' try: pdf_document = fitz.open(pdf_path) for page_num in range(pdf_document.page_count): page = pdf_document.load_page(page_num) text += page.get_text() pdf_document.close() except Exception as e: print(f"读取文件失败: {pdf_path}, 错误信息: {e}") return text def get_unique_pdfs(pdf_paths): unique_files = [] text_cache = set() # 缓存已出现的PDF文本,快速判断重复 for pdf_path in pdf_paths: pdf_text = extract_text_from_pdf(pdf_path) # 文本非空且未在缓存中,才加入唯一列表 if pdf_text and pdf_text not in text_cache: unique_files.append(pdf_path) text_cache.add(pdf_text) return unique_files # 获取结果并打印 unique_pdfs = get_unique_pdfs(pdf_paths) print("唯一PDF文件列表:") for pdf in unique_pdfs: print(pdf)
修正思路说明
- 顺序保证:
os.walk会按目录层级顺序遍历文件,首次出现的文件会先被处理,符合“保留首次出现”的需求。 - 缓存优化:用
set缓存已提取的PDF文本,判断重复的时间复杂度为O(1),同时避免重复提取同一文件的文本。 - 异常处理:添加了PDF读取异常捕获,避免单个文件读取失败导致整个程序崩溃。
- 逻辑简化:直接遍历每个文件,判断其文本是否已存在,不存在则加入唯一列表,逻辑清晰易懂。
内容的提问来源于stack exchange,提问作者Alan Chu2
相关产品推荐
相关产品推荐

