2

我正在使用此代码来查找两个 csv 列表之间的差异并提出一些格式问题。这可能是一个简单的解决方法,但我是新手,正在努力学习并遇到很多问题。

 import difflib

 diff=difflib.ndiff(open('test1.csv',"rb").readlines(), open('test2.csv',"rb").readlines()) 

 try:
  while 1:
    print diff.next(),
except:
 pass

代码工作正常,我得到我正在寻找的输出:

 Group,Symbol,Total

 - Adam,apple,3850

 ?           ^
 + Adam,apple,2850

 ?           ^
 bob,orange,-45

 bob,lemon,66

 bob,appl,-56

 bob,,88

我的问题是如何清理格式,我可以将 Group、Symbol、Total 分成单独的列,并将下面的文本排列起来吗?

我也可以改变吗?代表我确定的文本?比如 test 1 和 test 2 代表它来自哪个表?

谢谢你的帮助

4

3 回答 3

5

使用difflib.unified_diff提供了更清晰的输出,见下文。

此外,两者都difflib.ndiff返回difflib.unified_diff一个Differ对象,它是一个生成器对象,您可以直接在for 循环中使用它,并且知道何时退出,因此您不必自己处理异常。注意;后面的逗号line是为了防止print添加另一个换行符。

import difflib
s1 = ['Adam,apple,3850\n', 'bob,orange,-45\n', 'bob,lemon,66\n', 
      'bob,appl,-56\n', 'bob,,88\n']
s2 = ['Adam,apple,2850\n', 'bob,orange,-45\n', 'bob,lemon,66\n', 
      'bob,appl,-56\n', 'bob,,88\n']

for line in difflib.unified_diff(s1, s2, fromfile='test1.csv',
                 tofile='test2.csv'): 
    print line,

这给出了:

--- test1.csv
+++ test2.csv
@@ -1,4 +1,4 @@
-Adam,apple,3850
+Adam,apple,2850
 bob,orange,-45
 bob,lemon,66
 bob,appl,-56

因此,您可以清楚地看到在test1.csv和之间更改了哪些行test1.csv

于 2012-09-20T20:45:14.997 回答
1

要排列列,您必须使用字符串格式。

例如print "%-20s %-20s %-20s" % (row[0],row[1],row[2])

要将 更改?为您喜欢的任何文本测试,您可以使用s.replace('any text i like').

于 2012-09-20T22:07:04.037 回答
0

您的问题与 CSV 格式有关,因为difflib不知道它正在查看柱状字段。您需要弄清楚指南指向哪个字段,以便在打印列时可以调整它。

如果您的 CSV 文件很简单,即它们不包含任何带有嵌入式逗号或(不寒而栗)换行符的引用字段,您可以使用split(',')将它们分隔为字段,并找出指南指向的位置,如下所示:

def align(line, guideline):
    """
    Figure out which field the guide (^) points to, and the offset within it.
    E.g., if the guide points 3 chars into field 2, return (2, 3)
    """
    fields = line.split(',')
    guide = guideline.index('^')
    f = p = 0
    while p + len(fields[f]) < guide:
        p += len(fields[f]) + 1     # +1 for the comma
        f += 1
    offset = guide - p
    return f, offset

现在很容易正确地显示指南。假设您想通过打印 12 个空格宽的所有内容来对齐列:

diff=difflib.ndiff(...)
for line in diff:
    code = line[0]  # The diff prefix
    print code,
    if code == '?':
        fld, offset = align(lastline, line[2:])
        for f in range(fld):
            print "%-12s" % '',
        print ' '*offset + '^'
    else:
        fields = line[2:].rstrip('\r\n').split(',')
        for f in fields:
            print "%-12s" % f,
        print
        lastline = line[2:]

请注意,解析 CSV 文件的唯一可靠方法是使用该csv模块(或可靠的替代方法);但是让它与 diff 格式(完全通用)一起玩会有点头疼。如果您主要对可读性感兴趣并且您的 CSV 不是太粗糙,那么您可能会遇到偶尔的混淆。

于 2012-09-22T19:54:46.417 回答