我有两个文本。
T0 ID A
T1 ID B
T2 ID C
T4 ID D
和
T5 ID A
T6 ID E
T7 ID F
T8 ID D
我真的只想比较ID的序列,字母的差异。但是我想在输出中保留每个元素的第一部分,所以我可以在以后用它进行其他分析,即输出看起来像这样
@-1,2 +1,2
-T2 ID B
-T3 ID C
+T6 ID E
+T7 ID F
做这种差异的最佳方法是什么?理想情况下使用difflib python库。
另外,我说有两个对象列表,而不是2个文本,每个都有2个属性(object.t返回T1,object.ID返回B),我想只在对象列表上执行diff尊重他们的ID属性。我可以执行这样的操作吗?也许这应该是一个不同的问题。
由于
答案 0 :(得分:0)
您可以创建一个str
的子类,其哈希值和比较值就好像它只包含其ID:
import re
class IdString(str):
"""A string that hashes and compares on its id.
>>> hash(IdString('XXX ID A XXX')) == hash('A')
True
>>> hash(IdString('XXX ID abc XXX')) == hash('abc')
True
>>> IdString('XXX ID A XXX') == IdString('YYY ID A YYY')
True
>>> IdString('XXX ID A XXX') == IdString('XXX ID B XXX')
False
"""
def __new__(cls, *args):
self = super(IdString, cls).__new__(cls, *args)
m = re.search(r'\bID (\w+)', self)
self.id = m.group(1)
return self
def __hash__(self):
return hash(self.id)
def __eq__(self, other):
return self.id == other.id
def __ne__(self, other):
return self.id != other.id
然后,您可以将普通字符串转换为IdString
个对象,并将其传递给difflib
,如下所示:
from difflib import unified_diff
text1 = '''T0 ID A
T1 ID B
T2 ID C
T4 ID D
'''
text2 = '''T5 ID A
T6 ID E
T7 ID F
T8 ID D
'''
print(''.join(unified_diff(map(IdString, text1.splitlines(True)),
map(IdString, text2.splitlines(True)),
n=0)))
几乎产生你想要的输出:
---
+++
@@ -2,2 +2,2 @@
-T1 ID B
-T2 ID C
+T6 ID E
+T7 ID F
(你问题中的例子是@-1,2 +1,2
,但我无法完全重现,因为我不知道差异的样式是什么,而行号在diff输出中从1开始。)