2015-06-25 3 views
3

У меня есть программа, которая читает CSV-файл, проверяет любое несоответствие длины столбца (сравнивая его с полями заголовка), которое затем возвращает все, что было обнаружено в виде списка (а затем записывает в файл) , То, что я хочу делать с этим списком, чтобы перечислить результаты следующим образом:Как найти дубликаты в списке python, которые смежны друг с другом и перечислить их по индексам?

номера строк, где встречается то же несоответствие: количество столбцов в этой строке

например

rows: n-m : y 

где n и m - числа строк, которые имеют одинаковое количество столбцов, которые не соответствуют заголовку.

Я смотрел на эти темы, и в то время как информация может быть полезной, они не дают ответа на вопрос:

Find and list duplicates in a list?

Identify duplicate values in a list in Python

Это где я сейчас:

r = csv.reader(data, delimiter= '\t') 
columns = [] 
for row in r: 
     # adds column length to a list 
     colm = len(row) 
     columns.append(colm) 

b = len(columns) 
for a in range(b): 
     # checks if the current member matches the header length of columns 
     if columns[a] != columns[0]: 
       # if it doesnt, write the row and the amount of columns in that row to a file 
       file.write("row " + str(a + 1) + ": " + str(columns[a]) + " \n") 

Выход файла выглядит следующим образом:

row 7220: 0 
row 7221: 0 
row 7222: 0 
row 7223: 0 
row 7224: 0 
row 7225: 1 
row 7226: 1 

, когда желаемый конечный результат

rows 7220 - 7224 : 0 
rows 7225 - 7226 : 1 

Так что то, что я в основном нужно, как я понимаю, является словарь, где ключ строки с повторяющимся значением и значением является количество столбцов это сказанное несоответствие. То, что я в основном думаю, что мне нужно (в ужасном письменном псевдокоде, что не имеет никакого смысла теперь, когда я читаю его лет после написания этого вопроса), здесь:

def pseudoList(): 
    i = 1 
    ListOfLists = [] 
    while (i < len(originalList)): 
     duplicateList = [] 
     if originalList[i] == originalList[i-1]: 
      duplicateList.append(originalList[i]) 
     i += 1 
    ListOfLists.append(duplicateList) 


def PseudocreateDict(ListOfLists): 
    pseudoDict = {} 
    for x in ListOfLists: 
     a = ListOfLists[x][0]     #this is the first node in the uniqueList created 
     i = len(ListOfLists) - 1 
     b = listOfLists[x][i] #this is the last node of the uniqueList created 
     pseudodict.update('key' : '{} - {}'.format(a,b)) 

Это, однако, кажется очень запутанным способ делать то, что я хочу, поэтому мне было интересно, есть ли более эффективный способ b) более простой способ сделать это?

ответ

1

Вы можете использовать список понимание, чтобы возвращать список элементов в списке столбцов, которые отличаются от соседних элементов, которые будут конечными точками вашего диапазоны. Затем перечислите эти диапазоны и распечатайте/запишите те, которые отличаются от первого (заголовочного) элемента. В список диапазонов добавляется дополнительный элемент для указания индекса конца списка, чтобы избежать индексации вне диапазона.

columns = [2, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 2, 1]; 

ranges = [[i+1, v] for i,v in enumerate(columns[1:]) if columns[i] != columns[i+1]] 
ranges.append([len(columns),0]) # special case for last element 
for i,v in enumerate(ranges[:-1]): 
    if v[1] != columns[0]: 
     print "rows", v[0]+1, "-", ranges[i+1][0], ":", v[1] 

выход:

rows 2 - 5 : 1 
rows 6 - 9 : 0 
rows 10 - 11 : 1 
rows 13 - 13 : 1 
0

Что вы хотите сделать, это операция отображения/уменьшения, но без сортировки, которая обычно выполняется между отображением и уменьшением.

Если выход

row 7220: 0 
row 7221: 0 
row 7222: 0 
row 7223: 0 

на стандартный вывод, можно направить эти данные в другую питона программу, которая генерирует группы, которые вы хотите.

Вторая программа питон может выглядеть примерно так:

import sys 
import re 


line = sys.stdin.readline() 
last_rowid, last_diff = re.findall('(\d+)', line) 

for line in sys.stdin: 
    rowid, diff = re.findall('(\d+)', line) 
    if diff != last_diff: 
     print "rows", last_rowid, rowid, last_diff 
     last_diff = diff 
     last_rowid = rowid 

print "rows", last_rowid, rowid, last_diff 

Вы бы выполнять их, как это в среде UNIX, чтобы получить выход в файл:

python yourprogram.py | python myprogram.py > youroutputfile.dat 

Если вы не можете запустить это в среде unix, вы все равно можете использовать алгоритм, который я написал в вашей программе, с несколькими изменениями.

1

Вы также можете попробовать следующий код -

b = len(columns) 
check = 0 
for a in range(b): 
     # checks if the current member matches the header length of columns 
     if check != 0 and columns[a] == check: 
      continue 
     elif check != 0 and columns[a] != check: 
      check = 0 
      if start != a: 
       file.write("row " + str(start) + " - " + str(a) + ": " + str(columns[a]) + " \n") 
      else: 
       file.write("row " + str(start) + ": " + str(columns[a]) + " \n") 
     if columns[a] != columns[0]: 
       # if it doesnt, write the row and the amount of columns in that row to a file 
       start = a+1 
       check = columns[a]