Python 如果存在差异,是否获取具有相同id的项目的最小最大值?

Python 如果存在差异,是否获取具有相同id的项目的最小最大值?,python,difflib,Python,Difflib,我有两个看起来像这样的文件,它们之间有些不同: 第一个文件: {16:[3, [-7, 87, 20, 32]]} {17:[2, [-3, 88, 16, 28], 3, [-6, 84, 20, 32]]} {18:[2, [-1, 88, 16, 28], 3, [-3, 84, 20, 32]]} {19:[2, [1, 89, 16, 28], 3, [-2, 85, 20, 32]]} {20:[2, [9, 94, 16, 28], 3, [1, 85, 20, 32]]} {2

我有两个看起来像这样的文件,它们之间有些不同:

第一个文件:

 {16:[3, [-7, 87, 20, 32]]}
{17:[2, [-3, 88, 16, 28], 3, [-6, 84, 20, 32]]}
{18:[2, [-1, 88, 16, 28], 3, [-3, 84, 20, 32]]}
{19:[2, [1, 89, 16, 28], 3, [-2, 85, 20, 32]]}
{20:[2, [9, 94, 16, 28], 3, [1, 85, 20, 32]]}
{21:[2, [12, 96, 16, 28], 3, [2, 76, 19, 31]]}
{22:[2, [15, 97, 16, 28], 3, [4, 73, 19, 29]]}
{23:[2, [18, 96, 16, 28], 3, [6, 71, 19, 29], 10, [-10, 60, 51, 82]]}
{24:[2, [22, 97, 16, 28], 3, [9, 71, 19, 27], 10, [-5, 63, 49, 78]]}
{25:[2, [25, 99, 16, 28], 3, [13, 71, 17, 26], 10, [-1, 64, 46, 77]]}
{26:[2, [29, 101, 16, 28], 3, [17, 70, 16, 25], 10, [-1, 65, 45, 77]]}
第二个文件:

{16:[3, [-7, 86, 20, 32]]}
{17:[2, [-3, 82, 16, 28], 3, [-6, 84, 20, 32]]}
{18:[2, [-1, 88, 16, 27], 3, [-3, 84, 20, 32]]}
{19:[2, [1, 89, 16, 28], 3, [-2, 84, 20, 32]]}
{20:[2, [9, 94, 15, 28], 3, [1, 85, 20, 32]]}
{21:[2, [12, 96, 16, 28], 3, [1, 76, 19, 31]]}
{22:[2, [15, 97, 17, 28], 3, [4, 73, 19, 29]]}
{23:[2, [18, 96, 18, 28], 3, [6, 71, 19, 29], 10, [-10, 60, 51, 82]]}
{24:[2, [22, 97, 16, 28], 3, [9, 71, 20, 27], 10, [-5, 63, 49, 78]]}
{25:[2, [25, 99, 16, 28], 3, [13, 71, 17, 26], 10, [-1, 64, 46, 77]]}
{26:[2, [29, 101, 17, 28], 3, [17, 70, 16, 25], 10, [-1, 65, 45, 77]]}
我使用difflib对它们进行比较,并打印出其中有差异的行。 我要做的是打印出共享相同
id
的最小和最大

帧是每行中的关键帧,因此本例中的帧范围为
16
26
。id是每个4个值列表前面的值。因此,第一行上的id是
3
。第二行有两个id,分别是
2
3

我想写的一个例子是:

17 - 36
假设共享id
3
帧之一与我正在比较的文件不同

对于这样的每个差异,我需要写出一个只包含开始帧和结束帧的新文件,然后我将致力于将附加字符串连接到每个文件

这是当前difflib使用情况,它打印出具有不同

def compare(f1, f2):
    with open(f1+'.txt', 'r') as fin1, open(f2+'.txt', 'r') as fin2:
        diff = difflib.ndiff(fin1.readlines(), fin2.readlines())
        outcome = ''.join(x[2:] for x in diff if x.startswith('- '))
        print outcome
通过调整此执行块,我将如何实现上面所述的功能


请注意,这两个文件共享相同的
frame
amount,但不相同的
id
s,因此我需要为每个差异编写两个不同的文件,可能会写入一个文件夹。因此,如果这两个文件有20个差异,我需要有两个主文件夹,每个原始文件一个,每个原始文件包含相同id的每个开始和结束
帧的文本文件。

假设您的差异列表是您在文章开头给出的文件内容。我进行了2次,第一次获得每个id的帧列表:

>>> from collections import defaultdict
>>> diffs = defaultdict(list)
>>> for line in s.split('\n'):
    d = eval(line) # We have a dict
    for k in d: # Only one value, k is the frame
        # Only get even values for ids
        for i in range(0, len(d[k]), 2):
            diffs[d[k][i]].append(k)


>>> diffs # We now have a dict with ids as keys :
defaultdict(<type 'list'>, {10: [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36], 2: [17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33], 3: [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36], 29: [31, 32, 33, 34, 35, 36]})
然后,对于每个id,都有差异的范围。我想只要稍加调整,你就能得到你想要的

编辑:以下是相同类型块的最终答案:

>>> def compare(f1, f2):
    # 2 embedded 'with' because I'm on Python 2.5 :-)
    with open(f1+'.txt', 'r') as fin1:
        with open(f2+'.txt', 'r') as fin2:
            lines1 = fin1.readlines()
            lines2 = fin2.readlines()
                    # Do not forget the strip function to remove unnecessary '\n'
            diff_lines = [l.strip() for l in lines1 if l not in lines2]
                    # Ok, we have our differences (very basic)
            diffs = defaultdict(list)
            for line in diff_lines:
                d = eval(line) # We have a dict
                for k in d:
                    list_ids = d[k] # Only one value, k is the frame
                    for i in range(0, len(d[k]), 2):
                        diffs[d[k][i]].append(k)
            for id_ in diffs:
                diffs[id_].sort()
                for k, g in groupby(enumerate(diffs[id_]), lambda (i, x): i - x):
                    group = map(itemgetter(1), g)
                    print 'id {0} : {1} -> {2}'.format(id_, group[0], group[-1])

>>> compare(r'E:\CFM\Dev\Python\test\f1', r'E:\CFM\Dev\Python\test\f2')
id 2 : 17 -> 24
id 2 : 26 -> 26
id 3 : 16 -> 24
id 3 : 26 -> 26
id 10 : 23 -> 24
id 10 : 26 -> 26

假设您的差异列表是您在文章开头给出的文件内容。我进行了2次,第一次获得每个id的帧列表:

>>> from collections import defaultdict
>>> diffs = defaultdict(list)
>>> for line in s.split('\n'):
    d = eval(line) # We have a dict
    for k in d: # Only one value, k is the frame
        # Only get even values for ids
        for i in range(0, len(d[k]), 2):
            diffs[d[k][i]].append(k)


>>> diffs # We now have a dict with ids as keys :
defaultdict(<type 'list'>, {10: [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36], 2: [17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33], 3: [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36], 29: [31, 32, 33, 34, 35, 36]})
然后,对于每个id,都有差异的范围。我想只要稍加调整,你就能得到你想要的

编辑:以下是相同类型块的最终答案:

>>> def compare(f1, f2):
    # 2 embedded 'with' because I'm on Python 2.5 :-)
    with open(f1+'.txt', 'r') as fin1:
        with open(f2+'.txt', 'r') as fin2:
            lines1 = fin1.readlines()
            lines2 = fin2.readlines()
                    # Do not forget the strip function to remove unnecessary '\n'
            diff_lines = [l.strip() for l in lines1 if l not in lines2]
                    # Ok, we have our differences (very basic)
            diffs = defaultdict(list)
            for line in diff_lines:
                d = eval(line) # We have a dict
                for k in d:
                    list_ids = d[k] # Only one value, k is the frame
                    for i in range(0, len(d[k]), 2):
                        diffs[d[k][i]].append(k)
            for id_ in diffs:
                diffs[id_].sort()
                for k, g in groupby(enumerate(diffs[id_]), lambda (i, x): i - x):
                    group = map(itemgetter(1), g)
                    print 'id {0} : {1} -> {2}'.format(id_, group[0], group[-1])

>>> compare(r'E:\CFM\Dev\Python\test\f1', r'E:\CFM\Dev\Python\test\f2')
id 2 : 17 -> 24
id 2 : 26 -> 26
id 3 : 16 -> 24
id 3 : 26 -> 26
id 10 : 23 -> 24
id 10 : 26 -> 26

这很有帮助,非常感谢!但是,我不明白s.split('\n')中第三行中的“s”代表什么:哦,是的,对不起:-)
s
只是一个大字符串,包含了你在开头显示的所有行,它代表了差异列表。唯一的问题是我需要它来打印每个id的最小-最大帧,所以id 2:17->26左右…但是再次感谢,我会用它来解决问题。哦,好的,我想你你想要所有的范围!你只需要将diff中id的
后面的所有复杂逻辑替换为:
print min(diff[id]),max(diff[id])
就可以了。这非常有用,非常感谢!但是,我不明白s.split('\n')中第三行的“s”是什么意思:哦,是的,抱歉:-)
s
只是一个大字符串,包含开头显示的所有行,它代表差异列表。唯一的问题是我需要它打印每个id的最小-最大帧,所以id 2:17->26左右。。。但再次感谢你,我会解决这个问题,并尝试找出解决方案。哦,好的,我还以为你想要所有的范围呢!您只需将diff:
中id的
之后的所有复杂逻辑替换为:
printmin(diff[id])、max(diff[id])
,就可以完成了。