2012-06-19 4 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 

Мой вопрос, как я очищаю форматирование вверх, я могу сделать Group, Symbol, Всего в sperate columns, и выстроить текст ниже?

Также я могу изменить? представить текст, который я определяю? например, тест 1 и тест 2, представляющий, из какого листа он поступает?

спасибо за любую помощь

ответ

5

Использование difflib.unified_diff дает более чистый выходной сигнал, смотри ниже.

Кроме того, как и difflib.ndiffdifflib.unified_diff возвращают Differ объект, который является generator объект, который можно непосредственно использовать в цикле, и который знает, когда уйти, так что вам не придется обрабатывать исключения самостоятельно. 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.csv и test1.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 не слишком грубый, вы, вероятно, можете жить со случайным путаницей.

Смежные вопросы