使用 Python 打印列表列表之间的差异

Print differences between list of lists using Python

我有两个列表,如下所示。我知道我可以使用 set(list1)-set(list2) 或 vice-versa 来打印与其他相应列表不同的列表。但是,我不想打印出完整的列表,我只想要列表中已修改的部分。

例如,list1:

[['Code', 'sID', 'dID', 'cID', 'ssID'], ['ABCD-00', 'ABCD-00-UNK', '358', '1234', '9999'], ['ABCD-01', 'ABCD-00-UNK', 160, '993', '587']]

列表 2:

[['Code', 'sID', 'dID', 'cID', 'ssID', 'AddedColumn'], ['ABCD-00', 'ABCD-00-UNK', '358', '1234', '9999', 'AddedValue1'], ['ABCD-01', 'ABCD-00-UNK', 160, '993', 'ChangedValue', 'AddedValue2']]

如果我设置差异,它会打印出整个列表。当 'Code'、'sID' 相同时,我希望输出仅显示 different/added/taken 之外的列。

编辑:

每个列表列表的第一个列表是header。所以我想在 'Code'、'sID' 列的值匹配时比较列表。

期望的输出:

Added - ['AddedColumn', 'AddedValue1', 'AddedValue2']
Deleted - []
Changed - ['Code', 'ABCD-01', 'ssID', 'ChangeValue']

像这样或任何更简单的东西也可以。

使用 difflib.SequenceMatcher() 计算出您的列表发生了怎样的变化:

from difflib import SequenceMatcher

matcher = SequenceMatcher()
for a, b in zip(list1, list2):
    matcher.set_seqs(a, b)
    for tag, i1, i2, j1, j2 in matcher.get_opcodes():
        if tag == 'equal': continue
        print('{:>7s} {} {}'.format(tag, a[i1:i2], b[j1:j2]))

这个简单的设置仅列出已添加、删除或替换的内容:

>>> from difflib import SequenceMatcher
>>> list1 = [['Code', 'sID', 'dID', 'cID', 'sID'], ['ABCD-00', 'ABCD-00-UNK', '358', '1234', '9999'], ['ABCD-01', 'ABCD-00-UNK', 160, '993', '587']]
>>> list2 = [['Code', 'sID', 'dID', 'cID', 'sID', 'AddedColumn'], ['ABCD-00', 'ABCD-00-UNK', '358', '1234', '9999', 'AddedValue1'], ['ABCD-01', 'ABCD-00-UNK', 160, '993', 'ChangedValue', 'AddedValue2']]
>>> matcher = SequenceMatcher()
>>> for a, b in zip(list1, list2):
...     matcher.set_seqs(a, b)
...     for tag, i1, i2, j1, j2 in matcher.get_opcodes():
...         if tag == 'equal': continue
...         print('{:>7s} {} {}'.format(tag, a[i1:i2], b[j1:j2]))
... 
 insert [] ['AddedColumn']
 insert [] ['AddedValue1']
replace ['587'] ['ChangedValue', 'AddedValue2']

但是匹配器也会给你没有改变的东西;我忽略了 equal 标签以简化演示。它显示了如何添加两个元素,以及一个元素如何被另外两个元素替换。

set(a) - set(b) returns 列表 a 中但不在列表 b 中的元素。要查看添加到列表的元素,请使用 set(newList) - set(oldList),要查看从列表中删除的元素,请使用 set(oldList) - set(newList).

如果您在 python 3 中的列表列表中应用 set,则无法应用(我不知道 python 2),您会收到以下错误:TypeError: unhashable type: 'list'.因此,您必须将其应用于每个相应的子列表。