2013-06-25 3 views
0

У меня возникает странный вопрос, который, несмотря на множество попыток, я не могу найти логику и правильный код проблемы.Сложный способ подсчета записей файла динамически

У меня есть файл в формате ниже:

aa:bb:cc dd:ee:ff 100 ---------->line1 
aa:bb:cc dd:ee:ff 101 ---------->line2 
dd:ee:ff aa:bb:cc 230 ---------->line3 
dd:ee:ff aa:bb:cc 231 ---------->line4 
dd:ee:ff aa:bb:cc 232 ---------->line5 
aa:bb:cc dd:ee:ff 102 ---------->line6 
aa:bb:cc dd:ee:ff 103 ---------->line7 
aa:bb:cc dd:ee:ff 108 ---------->line8 
dd:ee:ff aa:bb:cc 233 ---------->line9 
gg:hh:ii jj:kk:ll 450 ---------->line10 
jj:kk:ll gg:hh:ii 600 ---------->line11 

Моя программа должна прочитать файл построчно. В первой строке и второй строке соответствующие значения столбца 1 и столбца2 равны. Третий столбец - это порядковый номер, который не является одинаковым для любых двух строк.
Так как строки1 и строка2 одинаковы, кроме того, их порядковые номера отличаются по значению только 1, я должен сначала прочитать эти две строки и записать их счет как 2 в выходной файл. Если мы заметим, строка 6 и строка 7 совпадают с строкой 1 и строкой 2, имеющей последовательные порядковые номера, но номера строк line3, line4, line5, имеющие разные столбцы 1 и столбцы 2, вошли между ними. Следовательно, линии (1 & 2) и линии (6 & 7) не следует группировать вместе. Итак, в выходном файле я должен получить результат как 2 3 2 1 1 1 1. И еще одно: строки 7 и 8 отличаются порядковым номером более 1. Следовательно, строка 8 следует считать отдельной записью , а не вместе с линиями 6 и 7, хотя линии 6,7,8 имеют одинаковые первые две колонки.
Я надеюсь, что большинство людей поняли вопрос. Если нет, я проясню что-нибудь по этому вопросу.
Как вы можете видеть, это очень сложная проблема. Я пробовал использовать словарь, поскольку это единственная структура данных, которую я знаю, но никакой логики не работает. Пожалуйста, помогите мне решить эту проблему.

+3

Я не вижу вопроса где-нибудь – Stephan

+0

@Stephan Вопрос в том, как я могу сгенерировать выходной файл, как я упомянул. –

+0

@JustinCarrey Просто повторите свой вопрос, чтобы быть более явным. – 2rs2ts

ответ

1
with open("abc") as f: 
    #read the first line and set the number from it as the value of `prev` 
    num, col4 = next(f).rsplit(None,2)[-2:] #use `str.rsplit` for minimum splits 
    prev = int(num) 
    col4_prev = col4 
    count = 1        #initialize `count` to 1 
    for lin in f: 
     num, col4 = lin.rsplit(None,2)[-2:] 
     num = int(num)      
     if num - prev == 1:    #if current `num` - `prev` == 1 
      count+=1      # increment `count` 
      prev = num      # set `prev` = `num` 
     else: 
      print count,col4_prev  #else print `count` or write it to a file 
      count = 1      #reset `count` to 1 
      prev = num      #set `prev` = `num` 
      col4_prev = col4 

    if num - prev != 1: 
     print count,col4 

выход:

2 400 
3 600 
2 400 
1 111 
1 500 
1 999 
1 888 

Где 'ABC' содержит:

aa:bb:cc dd:ee:ff 100 400 
aa:bb:cc dd:ee:ff 101 400 
dd:ee:ff aa:bb:cc 230 600 
dd:ee:ff aa:bb:cc 231 600 
dd:ee:ff aa:bb:cc 232 600 
aa:bb:cc dd:ee:ff 102 400 
aa:bb:cc dd:ee:ff 103 400 
aa:bb:cc dd:ee:ff 108 111 
dd:ee:ff aa:bb:cc 233 500 
gg:hh:ii jj:kk:ll 450 999 
jj:kk:ll gg:hh:ii 600 888 
+0

@ Ашвини .... Великий ты всегда мой спаситель. Я более маленький вопрос. Предположим, что каждая строка имеет 4 столбца вместо 3. и четвертый столбец является целым числом. Например, поскольку строки1 и строка2 сгруппированы вместе, скажем, что они имеют одинаковое значение в 4 столбцах. Как я могу извлечь/распечатать значение 4-го столбца вместе с подсчетом? –

+0

@JustinCarrey см. Мое обновленное решение. Это то, что вы хотели? –

+0

@ Ashwini..no, не так.Например, у меня есть первые две строки: aa: bb: cc dd: ee: ff 100 400; aa: bb: cc dd: ee: ff 101 400, Как распечатать счет, 4-й столбец; в этом случае, 2 400 –

0
from collections import defaultdict 
results = defaultdict(int) 
for line in open("input_file.txt", "r"): 
    columns = line.split(" ") 
    key = " ".join(columns[:2]) 
    results[key] += 1 

with output_file = open("output_file.txt", "w"): 
    for key, count in results: 
     output_file.write("{0} -> {1}".format(key, count)) 
0
entries = open('filename.txt', 'r') 
prevLine = "" 
count = 1 
for line in entries: 
    if line == prevLine: 
     count += 1 
    else: 
     print count 
     count = 1 
    prevLine = line 

Это должно сделать это, вот объяснение: Сначала вы открываетефайл , тогда вы перебираете каждую строку файла для каждой строки, которую вы сравниваете с предыдущей, , если она такая же, как и предыдущая, вы добавляете ее в счетчик совпадений , если это не то же самое, вы печатаете выход и сброса счетчика в конце цикла вы сохраните предыдущую строку

0

вы можете использовать itertools.groupby() ...

from cStringIO import StringIO 
import itertools 

data = 'aa:bb:cc dd:ee:ff 100\n' \ 
     'aa:bb:cc dd:ee:ff 101\n' \ 
     'dd:ee:ff aa:bb:cc 230\n' \ 
     'dd:ee:ff aa:bb:cc 231\n' \ 
     'dd:ee:ff aa:bb:cc 232\n' \ 
     'aa:bb:cc dd:ee:ff 102\n' \ 
     'aa:bb:cc dd:ee:ff 103\n' \ 
     'aa:bb:cc dd:ee:ff 108\n' \ 
     'dd:ee:ff aa:bb:cc 233\n' \ 
     'gg:hh:ii jj:kk:ll 450\n' \ 
     'jj:kk:ll gg:hh:ii 600\n' 

sio = StringIO(data) 
print [len(list(g)) for k, g in itertools.groupby(sio, key=lambda x, c=itertools.count(): (x[:-5], int(x[-4:-1])-next(c)))] 

... который печатает ...

[2, 3, 2, 1, 1, 1, 1]