You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

修正思路说明

  1. 顺序保证:os.walk会按目录层级顺序遍历文件,首次出现的文件会先被处理,符合“保留首次出现”的需求。
  2. 缓存优化:用set缓存已提取的PDF文本,判断重复的时间复杂度为O(1),同时避免重复提取同一文件的文本。
  3. 异常处理:添加了PDF读取异常捕获,避免单个文件读取失败导致整个程序崩溃。
  4. 逻辑简化:直接遍历每个文件,判断其文本是否已存在,不存在则加入唯一列表,逻辑清晰易懂。

内容的提问来源于stack exchange,提问作者Alan Chu2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 05:59:51