2017-02-16 18 views
2

Я пытаюсь извлечь определенные строки из выходного файла txt. Строки, которые меня интересуют, - это несколько строк выше и немного ниже key_string, которые я использую для поиска результатов. Строка ключа одинакова для каждого результата.Python: ссылаясь на каждый повторяющийся элемент в списке по уникальному индексу

fi = open('Inputfile.txt') 
fo = open('Outputfile.txt', 'a') 

lines = fi.readlines() 
filtered_list=[] 

for item in lines: 
    if item.startswith("key string"): 
     filtered_list.append(lines[lines.index(item)-2]) 
     filtered_list.append(lines[lines.index(item)+6]) 
     filtered_list.append(lines[lines.index(item)+10]) 
     filtered_list.append(lines[lines.index(item)+11])  
fo.writelines(filtered_list) 

fi.close() 
fo.close() 

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

ответ

1

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

Прежде всего, давайте найдем индексы всех соответствующих строк.

key = "key string" 
relevant = [] 
for i, item in enumerate(lines): 
    if item.startswith(key): 
     relevant.append(item) 

enumerate на самом деле довольно простой. Он принимает список и возвращает последовательность пар (индекс, элемент). Итак, enumerate(['a', 'b', 'c']) возвращает [(0, 'a'), (1, 'b'), (2, 'c')].

То, что я написал выше, может быть достигнуто с помощью списка понимания:

relevant = [i for (i, item) in enumerate(lines) if item.startswith(key)] 

Таким образом, мы имеем показатели соответствующих строк. Теперь давайте соберем их. Вас интересует линия 2 линии перед ней и 6 и 10 и 11 строк после нее. Если ваши первые строки содержат ключ, тогда у вас есть проблема - вы действительно не хотите lines[-1] - это последний элемент! Кроме того, вам нужно обработать ситуацию, в которой ваше смещение приведет вас к концу списка: иначе Python будет поднимать IndexError.

out = [] 
for r in relevant: 
    for offset in -2, 6, 10, 11: 
     index = r + offset 
     if 0 < index < len(lines): 
      out.append(lines[index]) 

Вы также могли поймать IndexError, но это не спасет нас много печатать, так как мы должны обрабатывать отрицательные индексы в любом случае.

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

key = "key string" 
with open('Inputfile.txt') as fi: 
    lines = fi.readlines() 

relevant = [i for (i, item) in enumerate(lines) if item.startswith(key)] 
out = [] 
for r in relevant: 
    for offset in -2, 6, 10, 11: 
     index = r + offset 
     if 0 < index < len(lines): 
      out.append(lines[index]) 

with open('Outputfile.txt', 'a') as fi: 
    fi.writelines(out) 
+0

Спасибо, Ryszard! Это именно то, что я искал. Проблема заключалась в том, что извлеченные данные были только первой записью, дублированной по количеству записей в выходном файле. Это связано с тем, что метод python list.index имеет некоторые ограничения. Ниже приведено описание метода list.index из документации python 3.6: «Возвращенный индекс вычисляется относительно начала полной последовательности, а не аргумента start». – Bart

0

Чтобы избавиться от дубликатов, вы можете указать список для набора; Пример:

x=['a','b','a'] 
y=set(x) 
print(y) 

приведет: [ «а», «б»]

+0

Спасибо за ответ! Однако мне нужны эти дубликаты, чтобы использовать их в качестве якорей для извлечения данных, которые я хочу. К сожалению, ваш ответ мне не поможет. – Bart