我有两个列表,如下所示。我知道我可以使用set(list1)-set(list2)或反之亦然来打印与其他对应列表不同的列表。但是,我不希望打印出完整的列表,我只是希望列表中的那部分被修改。
例如,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']]
如果我设置了差异,它会打印出整个列表。我希望输出只显示不同/添加/删除的列,而代码',' sID'是相同的。
每个列表列表的第一个列表是标题。所以我想比较来自' Code',' sID'列匹配。
期望的输出:
Added - ['AddedColumn', 'AddedValue1', 'AddedValue2']
Deleted - []
Changed - ['Code', 'ABCD-01', 'ssID', 'ChangeValue']
类似这样或更简单的东西也可以。
我试过的代码:
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]))
它可以很好地比较相应的列表,即list1中的sub-list1和list2中的sub-list1。但是我希望它在整个列表中进行比较,因为如果缺少某个特定的子列表,它会打印出一切都不同。通过子列表我的意思是,例如list1中的['Code', 'sID', 'dID', 'cID', 'ssID']
是子列表1。
答案 0 :(得分:1)
所以 - 正如人们在评论中所说的那样,你真正应该做的是将你称为“子列表”的每组数据读入适当的对象 - 并且比较这些对象的属性。
例如,要坚持使用本机类型,如果“代码”和“sID”构成您的密钥,则每行可以是由代码元组和sid值键入的字典。
但是htis问题似乎需要一个自定义类 - -
鉴于上面的一个列表 - 你几乎可以从一开始就开始:
class MyThing(object):
def __init__(self, *args):
for attrname, arg in zip(['Code', 'sID', 'dID', 'cID', 'ssID'], args):
setattr(self, attrname, arg)
def __hash__(self):
# This is not needed for the OrderedDict bwellow, but allows you
# to use sets with the objects if you want
return hash(self.Code + self.sID)
from collections import OrderedDict
myobjs = OrderedDict()
for line in list1[1:]:
obj = MyThing(line)
id = obj.Code + obj.sId
if id in myobjs:
# do your comparisson -logging -printing stuff here
else:
myobjs[id] = obj
实际上可以在没有类和对象创建部分的情况下完成 - 只需将“行”存储在字典中 - 但是该类使您能够以更清洁的方式执行许多操作。复杂的__init__
只是一种不复制大量self.sId = sId
行的简写。
答案 1 :(得分:0)
这是我的基本解释。 OP对于他们对{{1}}列表的要求并不十分清楚 - 所以他们应该更具体地更新他们的要求。正如jsbueno所暗示的那样,dict可能会更好 - 这实际上取决于,如果这是它的格式,那么列表会更便宜。
changed
示例输出:
added = []
deleted = []
changed = []
for sub_l1, sub_l2 in zip(l1, l2):
for i in range(min(len(sub_l1), len(sub_l2))):
if sub_l1[i] != sub_l2[i]:
changed.append(sub_l2[i])
if len(sub_l2) > len(sub_l1):
added.append(sub_l2[len(sub_l1):len(sub_l2)])
elif len(sub_l1) > len(sub_l2):
deleted.append(sub_l1[len(sub_l2):len(sub_l1)])
请注意,In [66]: added
Out[66]: [['AddedColumn'], ['AddedValue1'], ['AddedValue2']]
In [67]: deleted
Out[67]: []
In [68]: changed
Out[68]: ['ChangedValue']
并未告诉您哪个值发生了更改,通常您可能需要一个包含CSV子列表和列号的元组。