
はじめに
第18回では フォルダ内のファイル一覧表示 を作って、pathlib
でファイル情報を扱ったな。
今回はテキスト整形の定番ワーク、「重複行削除ツール」 に挑戦しよう!
ログや名簿、タグ一覧など、同じ行が紛れ込む問題はよくある。
重複を取り除き、最初の順序を保ったまま きれいに整える実用ツールを作るで。
完成イメージ
names.txt
(入力)
Alice Bob Alice Charlie Bob
プログラム実行後の unique.txt
(出力)
Alice Bob Charlie
ヒント(使う要素)
with open(..., "r")
/"w"
:ファイル読み書きset()
:すでに見た行の管理に便利- 順序保持:
set
だけでなく、最初の出現順を維持するロジックがコツ strip()
:末尾の改行や余分な空白の扱いをそろえる
コード全文(基本版:順序保持)
まずは最初に出てきた順番を維持しながら、完全一致の重複を消す最小構成や。
# Lesson 19: 重複行削除ツール(基本版:順序保持) src = "names.txt" # 入力ファイル dst = "unique.txt" # 出力ファイル seen = set() unique_lines = [] with open(src, "r", encoding="utf-8") as f: for line in f: line = line.rstrip("\n") # 改行のみ除去(空白は保持) if line not in seen: seen.add(line) unique_lines.append(line) with open(dst, "w", encoding="utf-8") as f: for line in unique_lines: f.write(line + "\n") print(f"重複を削除しました:{src} → {dst}") print(f"元の行数:{len(seen) + (len(unique_lines) - len(seen))} / ユニーク行数:{len(unique_lines)}")
ポイント
rstrip("\n")
で改行だけ落とし、行頭・行末の空白は保持(厳密一致)。- 順序は
unique_lines
の積み上げ順で維持される。
改良版1:空白・大文字小文字を無視して判定
データの“ゆらぎ”をならしたいときは、比較キーを作って判定用に使う。
# Lesson 19: 重複行削除ツール(改良版:空白・大文字小文字を無視) src = "names.txt" dst = "unique_normalized.txt" def norm(s: str) -> str: # 先頭末尾の空白を除去し、小文字化して比較キーを作る return s.strip().lower() seen = set() unique_lines = [] with open(src, "r", encoding="utf-8") as f: for raw in f: raw = raw.rstrip("\n") key = norm(raw) if key not in seen: seen.add(key) # 保存は“元の表示”を優先:raw を書き出す unique_lines.append(raw) with open(dst, "w", encoding="utf-8") as f: for line in unique_lines: f.write(line + "\n") print(f"重複(空白・大小無視)を削除しました:{src} → {dst}")
改良版2:削除数のレポート & 回数集計も出力
どの行が何回出てきたかを知れると、データクレンジングに役立つで。
# Lesson 19: 重複行削除ツール(改良版:回数集計 & レポート) from collections import Counter src = "names.txt" dst = "unique_with_report.txt" report = "duplicates_report.txt" lines = [] with open(src, "r", encoding="utf-8") as f: for line in f: lines.append(line.rstrip("\n")) # 完全一致でカウント cnt = Counter(lines) # 順序保持のユニーク seen = set() unique_lines = [] for line in lines: if line not in seen: seen.add(line) unique_lines.append(line) # 出力 with open(dst, "w", encoding="utf-8") as f: for line in unique_lines: f.write(line + "\n") # レポート出力(2回以上出現した行を列挙) with open(report, "w", encoding="utf-8") as r: r.write("--- 重複行レポート ---\n") total_dups = 0 for line, c in cnt.items(): if c > 1: r.write(f"{line} : {c} 回\n") total_dups += c - 1 r.write(f"\n削除された重複行の合計:{total_dups}\n") print(f"ユニーク出力:{dst} / レポート:{report}")
実行方法
- 対象テキスト(例:
names.txt
)を用意 - いずれかのコードを
lesson19.py
として保存 - ターミナルで実行:
python lesson19.py
(動かへん場合はpython3 lesson19.py
)
応用アイデア
- 巨大ファイル対応:行ごとに処理して逐次書き込み(メモリ節約)
- GUI化:
tkinter.filedialog.askopenfilename()
でファイル選択 - CSV向け:列を指定して重複判定(例:メールアドレス列のみ)
- 正規化戦略切替:厳密一致/空白無視/記号除去などをオプション化
まとめ
今回は 重複行削除ツール を作ったで!set
と 順序保持の発想、そして正規化キーを使うテクニックを押さえれば、
現場で“使える”データクレンジングが一気に進むんや。
👉 次回は Lesson 20: ファイル拡張子一括変換ツール。
画像やテキストの拡張子をまとめて変換する、地味に便利なアプリを作るで!