Python 中的 Difflib 模块

2024年8月29日 | 阅读 8 分钟

在接下来的教程中,我们将了解 Python 编程语言中的 Difflib 模块。我们将讨论该模块的功能以及基于其类的示例。

那么,让我们开始吧。

了解 Python Difflib 模块

Difflib 是 Python 编程语言中的一个内置模块,包含各种简单的函数和类,允许用户比较数据集。该模块以人类可读的格式提供这些序列比较的输出,使用增量(deltas)更有效地显示差异。

difflib 模块通常用于比较字符串序列。但只要它们是可哈希的,我们也可以用它来比较其他数据类型。我们知道一个对象是可哈希的,如果它的哈希值在其生命周期内不改变。

Python difflib 模块中最常用的类是 Differ 和 SequenceMatcher 类。还有一些其他的辅助类和函数可以帮助进行更具体的操作。让我们在接下来的部分中了解其中一些函数。

了解 SequenceMatcher 类

让我们首先从 difflib 模块一个相当不言自明的函数开始:SequenceMatcher。SequenceMatcher 函数将比较两个提供的字符串,并返回表示两个字符串之间相似度的数据。让我们通过 ratio() 对象来尝试这个函数。这个对象将以十进制格式返回比较数据。下面显示了该示例

示例

输出

First String: Welcome to Javatpoint
Second String: Welcome to Python tutorial
Sequence Matched: 0.5106382978723404

说明

在上面的代码片段中,我们首先导入了 difflib 模块以及 SequenceMatcher 类。然后我们定义了两个字符串值,我们将使用该类来比较它们。之后,我们创建了一个新的变量,它封装了带有两个参数 abSequenceMatcher 类。而该函数实际上接受三个参数:None, ab

为了让函数识别两个字符串,我们必须将每个字符串的值赋给方法的变量 SquenceMatcher(a = str_1, b = str_2)

一旦定义了所有必需的变量,并且 SequenceMatcher 至少提供了两个参数,我们现在就可以使用我们之前提到的 ratio() 对象打印该值。这个对象将确定两个字符串中相同字符的比例,并以小数形式返回输出。就像这样,我们比较了两个简单的字符串并得到了关于它们相似度的输出。

注意:ratio() 对象是 SequenceMatcher 类关联的少数对象之一。您可以查阅 Python 官方文档,了解更多与该类相关的对象,以对序列执行不同的操作。

了解 Differ 类

Differ 类被认为是 SquenceMatcher 的反义词;它接收文本行并找出字符串之间的差异。但是 Differ 类在利用增量(deltas)方面很特别,这使得它对人类来说更有效和更易读,以便发现差异。

例如,在比较两个字符串时,向第二个字符串插入新字符时,将在收到额外字符的行前面出现一个 ' + '。

正如我们可能猜到的,删除第一个字符串中可见的某些字符将导致 ' - ' 出现在第二行文本之前。

如果一行在两个序列中都相同,将返回 ' ',如果一行丢失,则出现 ' ? '。此外,我们还可以使用 ratio() 等属性,我们在前面的示例中已经讨论过。

让我们看下面的例子来理解 Differ 类的作用。

示例

输出

First String: They would like to order a soft drink
Second String: They would like to order a corn pizza
Difference between the Strings
- They would like to order a soft drink
?                            ^ ^^ ^^ ^^

+ They would like to order a corn pizza
?                            ^ ^^ ^ ^^^

说明

在上面的代码片段中,我们导入了 difflib 模块以及 Differ 类。然后我们定义了要比较的两个字符串。然后我们对这两个字符串调用了 splitlines() 函数。

语法

此函数允许我们按行而不是按字符来比较字符串。

一旦我们定义了一个包含 Differ 类的变量,我们就创建另一个包含 Differcompare() 对象的变量,该对象将两个字符串作为参数。

语法

我们调用 print() 函数,并通过换行符连接 my_diff 变量,以便输出的格式化方式使其更具可读性。

了解 get_close_matches 方法

difflib 模块提供了另一个简单但强大的工具,即 get_close_matches 方法。这个方法听起来完全符合它的名字:一个工具,它接受参数并返回目标字符串的最接近匹配项。用伪代码来说,该函数如下运行

语法

正如我们可以观察到上面的语法,get_close_matches() 方法接受四个参数;但是,它只需要前两个参数即可返回输出。

第一个参数是要定位的单词;我们希望该方法返回相似之处。第二个参数可以是变量数组或指向字符串数组的术语。第三个参数允许用户定义返回的输出数量的限制。最后一个参数确定两个单词之间需要有多大的相似度才能被作为输出返回。

仅使用前两个参数,该函数将根据默认截止值 0.6(范围在 0 - 1)和一个默认结果限制 3 来返回输出。让我们考虑下面的示例来理解该函数的工作原理。

示例

输出

Matching words: ['mass', 'mask', 'master']

说明

在上面的代码片段中,我们导入了 difflib 模块和 get_close_matches 方法。然后我们对一组具有某些字符相似性的项目使用了 get_close_matches() 方法。一旦我们执行程序,该函数将只返回三个包含相似字母的单词,尽管有第四个与“mas”相似的词:“massive”。现在,让我们尝试在下面的示例中定义一个 result_limit 和一个 cutoff

示例

输出

Matching words: ['mass', 'mask', 'master', 'massive']

说明

在上面的代码片段中,我们得到了四个结果,它们与“mas”这个词至少有 60% 的相似度。cutoff 与原始值相同,因为我们只定义了与默认值 0.6 相同的值。但是,我们可以更改此参数以使结果更严格或更不严格。越接近 1,约束条件就越严格。

了解 unified_diff & context_diff 类

difflib 中有两个类的工作方式相同:unified_diffcontext_diff。两者之间唯一的主要区别是结果。

unified_diff 类接受两个字符串数据,然后返回第一个字符串中被删除或插入的每个单词。

让我们看下面的例子以更好地理解。

示例

输出

--- 
+++ 
@@ -1,6 +1,6 @@
-Mark
-Henry
-Richard
-Stella
-Robin
+Arthur
+Joseph
+Stacey
+Harry
+Emma
 Employees

说明

在上面的代码片段中,我们导入了所需的模块,并定义了两个存储一些单词的变量。然后我们使用 unified_diff() 函数从第一个变量中删除单词,并将第二个变量中的单词添加到第一个变量中。结果是,我们可以观察到 unified_diff 返回被删除的单词,前面带有 - 符号,并返回添加的单词,前面带有 + 符号。最后一个单词 'Employees' 在两个字符串中都没有前缀。

context_diff 类的工作方式与 unified_diff 类似。但是,它不是揭示原始字符串中插入和删除了什么,而是通过返回带有 '!' 前缀的更改行来简单地显示哪些行已更改。

让我们看下面的例子来理解这个类的作用。

示例

输出

*** 
--- 
***************
*** 1,6 ****
! Mark
! Henry
! Richard
! Stella
! Robin
  Employees
--- 1,6 ----
! Arthur
! Joseph
! Stacey
! Harry
! Emma
  Employees

说明

在上面的示例中,我们使用 context_diff 来删除和添加第一个字符串中的单词。结果可以观察到,修改过的单词用 '!' 前缀标示。