2012-06-19 70 views
2

我使用此代碼來查找兩個csv列表之間的差異並提出一些格式問題。這可能是一個簡單的解決方案,但我是新手,並試圖學習和有很多問題。difflib python格式

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 

我的問題是如何清潔格式化了,我可以讓集團,符號,共成專欄,並在下面的文字排隊?

我也可以改變?代表我確定的文字?如測試1和測試2代表它來自哪張紙?

感謝您的幫助

回答

5

使用difflib.unified_diff給人乾淨多輸出,見下文。

而且,無論是difflib.ndiffdifflib.unified_diff返回Differ對象,它是一個generator對象,你可以直接使用for循環,而且知道什麼時候退出,這樣你就不必自己處理異常。 N.B; 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.csvtest1.csv之間變化。

1

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

E.g. print "%-20s %-20s %-20s" % (row[0],row[1],row[2])

要將?更改爲任何您喜歡的文字測試,您可以使用s.replace('any text i like')

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不太粗糙,那麼您可能偶爾會偶爾混淆。