
はじめに
第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: ファイル拡張子一括変換ツール。
画像やテキストの拡張子をまとめて変換する、地味に便利なアプリを作るで!