python實現文件內容去重

python 實現文件內容去重

   文本內容去重有很多很簡單的方法可以實現,很多編輯器自帶去除重複行的功能。寫這篇文章的原因主要有兩個

  1. 有的文本文件很大,超出了編譯器能讀取的範圍
  2. 能有代碼解決的代碼解決,寫好代碼可以在其他代碼中調用,更方便使用

 簡單的可以分爲兩種情況小文件和大文件,先來看小文件去重實現。如同把大象關冰箱一樣分三步:

  • 第一步,讀取文件每一行,並處理掉換行符
  • 第二步,將文件內容去重
  • 第三步,寫到新文件裏(把冰箱門關上)

 上代碼

def file_remove_same(input_file, output_file):
    """
        針對小文件去重
    :param input_file: 輸入文件
    :param out_file: 去重後出文件
    :return:
    """
    with open(input_file, 'r', encoding='utf8') as f, open(output_file, 'a', encoding='utf8') as ff:
        data = [item.strip() for item in f.readlines()]  # 針對最後一行沒有換行符,與其他它行重複的情況
        new_data = list(set(data))
        ff.writelines([item + '\n' for item in new_data if item])  # 針對去除文件中有多行空行的情況

 對於大文件幾十個G那種(更大的也別放在本地了,放數據庫)就不能加載到內存中了,強行加載到內存中直接報內存錯誤
 解決方案是:將文件按行讀取,根據內容生成一個指紋(md5值或者其他唯一可識別的值),將指紋存集合中,當逐行讀取的過程中判斷集合中是否已經含有該行元素的指紋。如果指紋沒有添加到集合中,則添加指紋到集合中並將此行追加輸出到輸出文件中。如果指紋已經在集合中了,說明此行與上面的某一行重複。

def gen_md5(data):
    """
        生成md5
    :param data: 字符串數據
    :return:
    """
    md5 = hashlib.md5()
    md5.update(data.encode('utf-8'))
    return md5.hexdigest()
    
 def big_file_remove_same(input_file, output_file):
    """
        針對大文件文件去重(將文件文件寫在一行的,沒有辦法去重)
    :param input_file:
    :param output_file:
    :return:
    """
    finger_print_set = set()
    with open(input_file, 'r', encoding='utf8') as f, open(output_file, 'w', encoding='utf8') as ff:
        for line in f:
            line_string = line.strip()
            finger_print = gen_md5(line_string)
            if finger_print not in finger_print_set:
                finger_print_set.add(finger_print)
                ff.write(line)

這樣解決大小文件去重的問題
還有一種極端情況,就是指紋集合非常大,將內存佔用溢出。這種情況幾乎不會遇到,做一個大致的估計:當這個指紋集合內存佔用到3G的時候,按照集合的佔用效率大致是67%算,就能容納2G的指紋,指紋按照md5值計算,就能容納6710萬行數據 。如果文件超過6710萬行可以考慮採用數據庫(redis)方案。數據庫方案有空再補充吧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章