【Python】difflibを使ってPythonで差分抽出

【Python】difflibを使ってPythonで差分抽出 プログラミング

diffコマンドは、とても便利です。
同じ機能をPythonでも利用できるのを知っていましたか?

これって、かなり可能性が広がることです。
そもそも、diffコマンドでの結果が見にくいと思いませんか?

そして、求めた差分も結局は人間の目で確認します。
でも、人間の目なんて信用できません。

つまり、diffコマンドには不満も多いということです。
この不満を解消する方法が、difflibになります。

本記事の内容

  • difflibとは?
  • difflibの機能と使い道

それでは、上記に沿って解説していきます。

difflibとは?

difflibモジュールは、Pythonの標準ライブラリです。
そのため、Pythonをインストールした時点でdifflibが利用可能となります。

公式な説明としては、シーケンスを比較するためのクラスと関数を提供すると記されています。
シーケンスの意味を確認しておきましょう。

シーケンスには、連続、順序、順番などの意味があります。
整列しているモノだとイメージすれば、わかりやすいかもしれません。

そのシーケンス同士を比較するのが、difflibモジュールです。
そして、difflibにはそのためのクラスや関数が用意されているということですね。

もっと簡単に表現します。
「diffコマンドをPythonから使えるようにしたモノ」
プログラマーからすれば、これで十分でしょう。

では、difflibに用意されたクラスや関数にはどのようなモノがあるのかを見ていきましょう。
diffコマンド以上の機能が備わっている可能性もあります。

difflibの機能と使い道

クラスは、以下の3つが用意されています。

  • Differ
  • HtmlDiff
  • SequenceMatcher

単純に比較した結果を表示するだけなら、diffコマンドで十分です。
Python上で利用する以上は、それ以上のことをやらないと意味がありません。

そう考えると、上の二つは必要ありません。
「SequenceMatcher」のみに絞りましょう。

SequenceMatcherオブジェクトが持つ関数は以下。

  • set_seqs
  • set_seq1
  • set_seq2
  • find_longest_match
  • get_matching_blocks
  • get_opcodes
  • get_grouped_opcodes
  • ratio
  • quick_ratio
  • real_quick_ratio

ratio関数は、シーケンスの類似度を測る値を算出します。
quick_ratio関数やreal_quick_ratio関数は、同じようなモノです。

個人的には、get_opcodes関数がPythonで使う価値ありと思います。
使い方は、以下。

表示結果を見れば、なんとなくわかるでしょう。
つまり、get_opcodes関数はaをbにするための方法を出力しています。

各値の説明は、以下を参考にしてください。

意味
‘replace’a[i1:i2] は b[j1:j2] に置き換えられる。
‘delete’a[i1:i2] は削除される。この時、j1 == j2 である。
‘insert’b[j1:j2] が a[i1:i1] に挿入される。この時 i1 == i2 である。
‘equal’a[i1:i2] == b[j1:j2] (サブシーケンスは等しい).

この情報があれば、差分をデジタルに把握できます。
デジタルに把握できるということは、プログラムからそのデータを利用可能になります。

もちろん、そのデータを用いてdiffコマンドと同じような結果も表示できるでしょう。
ただ、差分を表示するだけなら、Pythonでdifflibを使う意味はありません。

例えば、差分をデータベースやファイルに保存するとしましょう。
このことをシェルスクリプト(diffコマンド)でやろうとしたら、面倒ですよね。
しかし、Pythonならば特に詰まることなくできるでしょう。

このようにして、差分結果を蓄積することが可能になるのです。
そうすると、蓄積されたデータをもとにチェックすることができるようになります。

ここで、冒頭にあげた人間の目に対する不信を取り上げましょう。
「人間の目なんで信用できません」と書きました。

蓄積されたデータをもとにチェックするのと比べてどうでしょうか?
圧倒的に、データとプログラムの連合軍の方が信用できますよね。

このような小さな改善をする上でも、difflibが使えると感じています。

タイトルとURLをコピーしました