Python 在两个文本上执行差异,仅使用文本中每行的一部分

Python 在两个文本上执行差异,仅使用文本中每行的一部分,python,algorithm,diff,Python,Algorithm,Diff,我有两条短信 T0 ID A T1 ID B T2 ID C T4 ID D 及 我真正感兴趣的只是比较ID序列的不同,字母。但是我想在输出中保留每个元素的第一部分,这样我可以在以后的其他分析中使用它 @-1,2 +1,2 -T2 ID B -T3 ID C +T6 ID E +T7 ID F 做这种区别最好的方法是什么?最好使用difflib python库 另外,假设不是2个文本,而是2个对象列表,每个对象都有2个属性object.t返回T1,object.ID返回B,我只想对对象列表中

我有两条短信

T0 ID A
T1 ID B
T2 ID C
T4 ID D

我真正感兴趣的只是比较ID序列的不同,字母。但是我想在输出中保留每个元素的第一部分,这样我可以在以后的其他分析中使用它

@-1,2 +1,2
-T2 ID B
-T3 ID C
+T6 ID E
+T7 ID F
做这种区别最好的方法是什么?最好使用difflib python库

另外,假设不是2个文本,而是2个对象列表,每个对象都有2个属性object.t返回T1,object.ID返回B,我只想对对象列表中的ID属性进行区分。我能做这样的手术吗?也许这应该是一个不同的问题


谢谢

您可以创建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,但我无法准确地再现它,因为我不知道这是什么类型的差异,并且在差异输出中行号从1开始。

你的列表结构不清楚。您如何用Python表示它们?很抱歉,这有点含糊不清,让我们使用一个非常简单的纯文本示例。我还添加了一个问题,以涵盖对象列表的比较。
--- 
+++ 
@@ -2,2 +2,2 @@
-T1 ID B
-T2 ID C
+T6 ID E
+T7 ID F