每日一“酷”之difflib

介绍:difflib 比较序列。该模块包含一些用来计算和处理序列直接差异的工具。她对于比较文本尤其用,其中包含的函数可以使用多种常用差异格式生成报告。

测试数据(splitlines()按行划分为序列列表):

text1 = """
We all know that English is very useful. Many people in the world speak English. So more and more people in China study it.
How to study English well? I think we must have a good way to study English.
If you want to learn English well, listening, speaking, reading and writing are important.
You should listen to tapes every day. You should often speak English with your teachers and friends.
You should read English every morning. And, you had better keep a diary every day.
In this way, you can study English well.
"""
text1_lines = text1.splitlines()

text2 = """
We all know that English is very useful. Many people in the world speak English. So more and more people in China study it.
How to study English well? I think we must have a good way for study English.
If you wants to learn English well, listening, speaking, reading and writing are important.
He could not read music, but if he heard a tune a few times, he could play it.
You should listen to tapes every day. You should often speak English with your teachers and friends.
You should read English everyday morning. And, you had better keep a diary every day.
In this ways, you can study English well.
"""
text2_lines = text2.splitlines()

1、比较文本体

  Differ类 勇于处理文本序列,生成人类可读的差异或者更改指令,包括各行中的差异。Differ类生成的默认输出与UNIX下的diff命令行工具类似,包括两个列表的原始输入值(包含共同的值),以及指示做了哪些更改的标记数据。

  · 有“-”前缀的行指示这些行在第一个序列中,但不包含在第二个序列中

  · 有“+”前缀的行在第二个序列中,但不包含在第一个序列中

  · 如果某一行在不同版本之间存在增量差异,会使用一个以“?”为前缀的额外的行强调新版本的变更

  · 如果一行未改变,会输出该行,而且其左边有一个额外的空格,使它在与其他可能有差异的输出对齐

  将文本传入compare()之前先分解为由单个文本行构成的序列,与传入大字符串相比,这样可以生成更可读的输出

1 import difflib
2 from difflib_data import *
3 d = difflib.Differ()
4 diff = d.compare(text1_lines,text2_lines)
5 print ‘\n‘.join(diff)

运行结果:

  

上面是程序运行的结果,简单分析一下:

第一部分,是没有异常的即两段文字一样,就会原样输出。

第二部分与第三部分雷同,都是存在一定的差异,会用“-”与“+”号进行处理并标注在相应位置。

如果差异过长会完全删除老版本,而增加新版本。(compare(lt1,lt2)两者后者是新版本)

ndiff()函数生成的输出基本相同,会特别“加工”来处理文本数据,并删除输入中的“噪声”。用法:difflib.ndiff(lt1,lt2)

其他格式输出:

  Differ类会显示所有输入行,统一差异格式则不同,它只包含已修改的文本行和一些上下文,使用unified_diff()函数

演示:

  

 1 import difflib
 2 from difflib_data import *
 3 #unified_diff
 4 diff = difflib.unified_diff(text1_lines,
 5                             text2_lines,
 6                             lineterm=‘‘
 7                             )
 8 print ‘\n‘.join(list(diff))
 9 print ‘-----------------------‘
10 #context_diff
11 diff = difflib.context_diff(text1_lines,
12                             text2_lines,
13                             lineterm=‘‘
14                             )
15 print ‘\n‘.join(list(diff))

演示结果:

说明:lineterm 参数用来告诉unified_diff()不必为它返回的控制昂追加换行符,因为输入航不包含这些换行符。输出时所有都会则感觉换行符。

2、无用数据

  所有生成差异序列的函数都可以接受一些参数来指示应当忽略那些行,以及应当忽略一行中的那些字符,例如:可以用这些参数指定跳过一个文件两个本中的标记或者空白变更。

 1 from difflib import SequenceMatcher
 2 def show_result(s):
 3     i,j,k = s.find_longest_match(0,5,0,9)
 4     print ‘   i = %d‘ % i
 5     print ‘   j = %d‘ % j
 6     print ‘   k = %d‘ % k
 7     print ‘   A[i:i+k] = %r‘ % A[i:i+k]
 8     print ‘   B[j:j+k] = %r‘ % B[j:j+k]
 9
10 A = " abcd"
11 B = "abcd abcd"
12
13 print ‘A = %r‘ % A
14 print ‘B = %r‘ % B
15
16 print ‘\nWithout junk detection:‘
17 show_result(SequenceMatcher(None,A,B))

运行结果:

  

默认情况下,Differ不会显式忽略任何行或者字符,而回依赖SequenceMatcher 的能力检测噪声。ndiff()的默认行为时忽略空格和制表符。

3、比较任意类型

  SequenceMatcher类用于比较任意类型的两个系列,只要它们的值是可散列。这个类使用一个算法来标识序列中最长的链接匹配块,并删除对实际数据没有贡献的无用值。

实例:

  

 1 import difflib
 2 from difflib_data import *
 3
 4 s1 = [1,2,3,5,6,4]
 5 s2 = [2,3,5,4,6,1]
 6 print ‘Initial data:‘
 7 print ‘s1 = ‘,s1
 8 print ‘s2 = ‘,s2
 9 print ‘s1 == s2:‘, s1 == s2
10 print
11
12 matcher = difflib.SequenceMatcher(None,s1,s2)
13 for tag,i1,i2,j1,j2 in reversed(matcher.get_opcodes()):
14     if tag == ‘delete‘:
15         print ‘Remove %s from positions [%d : %d]‘ %16             (s1[i1:i2],i1,i2)
17         del s1[i1:i2]
18     elif tag == ‘equal‘:
19         print ‘s1[%d : %d] and s2[%d : %d] are the same‘ % 20             (i1,i2,j1,j2)
21     elif tag == ‘insert‘:
22         print ‘Insert %s from s2[%d : %d] into s1 at %d‘ % 23             (s2[j1:j2],j1,j2,i1)
24         s1[i1:i2] = s2[j1:j2]
25     elif tag == ‘replace‘:
26         print ‘Replace %s from s1[%d : %d] with %s from s2[%d : %d]‘ % 27             (s1[i1:i2],i1,i2,s2[j1:j2],j1,j2)
28         s1[i1:i2] = s2[j1:j2]
29     print ‘  s1 =‘,s1
30 print ‘s1 == s2:‘,s1 == s2

执行结果:

  

  这个例子比较了量证书列表,并使用get_opcodes()得到将原列表转换为新列表的指令,这里以逆序应用所做的修改,是的添加和删除元素之后雷暴索引仍是正确的。

  SwquenceMatcher 用于处理定制类以及内置类型,前提是它们必须是课散列的

时间: 2024-12-09 16:36:21

每日一“酷”之difflib的相关文章

每日一“酷”之heapq

作用:heapq模块实现一个适用于Python列表的最小堆排序算法 堆(heap)是一个属性数据结构,其中子节点与父节点是一种有序关系.二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树)或者是近似完全二元树(二叉树).可以使用以下如下方式组织的列表或数表示,即元素N的子元素位于2*N+1和2*N+2.这种布局允许原地重新组织堆,从而不必再增加或删除元素时分配大量内存. 最大堆确保父节点大于或等于其两个子节点.最小堆要求父节点小雨或等于其子节点.Python的heqpq模块实现了一个最小堆. 1.

每日一“酷”之array

array--国定类型数据序列 array模块定义一个序列数据结构,看起来和list非常相似,只不过所有成员都必须是相同的基本类型. 1.初始化 array实例化时可以提高一个参数来描述允许哪个种数据类型,还可以有一个初始的数据序列存储在数组中. 1 import array 2 import binascii 3 s = 'This is the array.' 4 a = array.array('c',s) 5 6 print 'As string:', s 7 print 'As arr

每日一“酷”之pprint

pprint – 美观打印 作用:美观打印数据结构 pprint 包含一个“美观打印机”,用于生成数据结构的一个美观视图.格式化工具会生成数据结构的一些表示,不仅可以由解释器正确地解析,而且便于人类阅读.输出尽可能放在一行上,分解为多行时则需要缩进. 这一节中的列子都用到了pprint_data.py,其中包含一下数据 1 data = [(1,{'a':'A','b':'B','c':'C','d':'D'}), 2 (2,{'e':'E','f':'F','g':'G','h':'H', 3

每日一“酷”之copy

Copy – 复制对象 作用:提供一些函数,可以使用浅副本或深副本语义复制对象. copy模块包括两个函数copy()和deepcopy(),用于复制现有的对象 1.  浅副本 copy()创建的浅副本(shallow copy)是一个新容器,其中填充原对象内容的引用.建立list对象的一个浅副本时,会构造一个新的list,并将原对象的元素追加到这个list. 1 import copy 2 3 class MyClass(object): 4 def __init__(self,name):

每日一“酷”之bisect

作用:维护有序列表,而不必在每次想列表增加一个元素时调用sort排序 bisect 模块实现了一个算法用于向列表中插入元素,同时仍保持列表有序.有些情况下,这比反复对一个了表序列更高效,另外也比构建一个大列表之后再显式对齐排序更为高效 1.有序插入 使用insort()按有序顺序像一个列表中插入元素 1 import bisect 2 import random 3 random.seed(1) 4 5 print 'New Pos Contents' 6 print '--- --- ----

每日一“酷”之Cookie

Cookie---Http Cookie 作用:Cookie模块定义一些类来解析和创建HTTP cookie首部 Cookie模块为大多数符合RFC 2109的cookie实现一个解析器.这个实现没有标准那么严格,因为,MSIE 3.0X并不支持整个标准. RFC 2109 HTTP状态管理机制 1.  创建和设置Cookie 可以用Cookie为机遇浏览器的应用实现状态管理,因此,Cookie通常由服务器设置,并由客户存储和返回.下面是一个创建cookie的最简单的例子. import Coo

每日一“酷”之textwrap

介绍:需要美观打印时,可以使用textwrap模块来格式化要输出的文本,这个模块允许通过编程提高类似段落自动换行或填充特性等功能. 1 创建实例数据 1 sample_text = ''' 2 I’m very happy and I like to make friends with others. 3 I also like singing but traveling is my favorite, I have been to many interesting places in Chin

每日一“酷”之Queue

Queue—线程安全的FIFO实现 作用:提供一个线程安全的FIFO实现 Queue模块提供了一个适用于多线程编程的先进先出(first-in,first-out)数据结构,可以用来在生产者和消费者线程之间安全地传递消息或其他数据.它会为调用者处理锁定,使多个线程可以安全第处理同一个Queue实例.Queue的大小(其中包含的元素个数)可能要受限制,,以限制内存使用或处理. 1.  基本FIFO队列 Queue类实现一个基本不能的先进先出容器.使用put()将元素增加到序列一段,使用get()从

每日一“酷”之string

介绍:string模块可以追溯到最早的Python版本中.现在很多的被移植为str和unicode对象的方法,在python3.0中会被完全去除.string模块中,有很多有用的常量和累,用来处理string和unicode对象. 一. 函数 1.capwords()的作用是将一个字符串中所有单词的首字母大写: 1 import string 2 s = 'We believe one thing,today is difficult,tomorrow is more difficult,but