Python сортировка List index out of range
Я пишу программу, которая удаляет повторяющиеся строки из исходного текстового файла. Программа принимает на вход два текстовых файла: первый файл (исходный) со множеством строк и второй, изначально пустой, для вывода уникальных строчек, отобранных из первого файла. Программа должна сохранять очередность следования строк.
init_tab = [] #переменная-список для строчек исходного файла
output_tab = [] #переменная-список для строк выходного файла
rdbin = open('remove_doubles_beta_input.txt', 'r', encoding="utf-8") #открыть исх. файл для чтения
rdbout = open('remove_doubles_beta_output.txt', 'r+', encoding="utf-8") #открыть вых. файл для чтения и записи
init_tab = rdbin.readlines() #заполнить переменную init_tab строками исх. файла с помощью .readlines()
init_enum = 0 #объявить переменную-счетчик для элементов списка init_tab, приравнять её к нулю
output_enum = 0 #объявить переменную-счетчик для элементов списка output_tab, приравнять её к нулю
while init_enum > -1: #начало цикла. Условие для while выбрано примитивное, я глупенький :(
output_tab = rdbout.readlines() #заполнить переменную init_tab строками вых. файла с помощью .readlines()
output_enum = 0 #в теле цикла переменная output_enum принудительно обнуляется, чтобы при каждой итерации перебор вых. списка начинался с самого начала
if not output_tab[output_enum]: #проверка отсутствия строк в выходном файле: данная проверка предназначена для заполнения пустого выходного файла первой строкой из исходного в начале работы программы
rdbout.write(init_tab[init_enum]) #заполнение файла rdbout значением init_enum (в данном случае равного нулю) элемента списка init_tab
elif output_tab[output_enum]: #альтернативная ветка условного оператора: выявляет случай, когда выходной файл уже НЕ является пустым
if init_tab[init_enum] == output_tab[output_enum]: #проверка: равняется ли значение выбранного элемента списка init_tab под номером init_enum значению строки списка output_tab под номером output_enum
init_enum = init_enum + 1 #если равенство имеет место, значит, в выходной файл уже передавалась такая строка, и в исходном списке init_tab выбирается следующий элемент, чей номер равен init_enum + 1
output_tab.clear() #я предполагаю, что в цикле программа не перечитывает заново выходной список, и принудительно очищаю его, чтобы заполнить вновь при следующей итерации
break #оператор break, как я предполагаю, должен перенести выполнение программы к строке, в которой находится условие while init_enum > -1. Возможно, я ошибаюсь
elif init_tab[init_enum] != output_tab[output_enum]: #альтернативная ветка подусловия: строка выходного списка не пуста и при этом не равняется отмеченной строке исходного списка
output_enum = output_enum + 1 #при таких условиях производится увеличение счетчика строки выходного списка
continue #оператор continue должен переносить выполнение программы в строку "if not output_tab[output_enum]:" (первое условие в коде программы)
rdbin.close() #закрыть исходный файл
rdbout.close() #закрыть выходной файл
И вот чего-то я не понимаю. При выполнении программа выдает такое сообщение:
Traceback (most recent call last):
File "D:\remove_doubles.py", line 14, in <module>
if not output_tab[output_enum]:
IndexError: list index out of range
Индекс в этом месте выполнения, по моей прикидке, равняется нулю. Если заранее записать в исходный файл какую-то строку и в этом месте кода (до условного оператора) попросить программу написать значение элемента output_tab[output_enum], программа спокойно выводит его в консоль. Я знаю, на стак оверфлоу творят чудеса. Помогите мне разобраться, пожалуйста, в чем я накосячил?
Ответы (2 шт):
output_tab изначально пустой список, в нем нет никакого элемента, даже нулевого (потому что нулевой элемент это первый в обычной жизни). Можно инициализировать список сразу с одним элементом, например
output_tab = [""]
Но по-хорошему лучше ловить исключение с помощью try..except.
Большое спасибо вам за помощь! Я долго искал способ удалить из исходного файла дубликаты строк с сохранением порядка следования. Один знакомый посоветовал мне воспользоваться более простым решением. Я начисто переписал скрипт, и в отличие от исходного, он работает. Никаких "List index out of range" нет и в помине. Помещаю этот код здесь со всеми комментариями. Программа выполняет считывание строк файла remove_duplicates_input.txt и записывает их в файл remove_duplicates_output.txt, исключая дубликаты. Понимаю, что изобрел велосипед, но буду рад, если этот скрипт будет кому-нибудь полезен.
ri = open('remove_duplicates_input.txt', 'r', encoding="utf-8") #открыть исходный файл для чтения
ro = open('remove_duplicates_output.txt', 'w+', encoding="utf-8") #открыть файл вывода для записи
s=ri.readlines() #заполнить список s строками из файла ri
p=[''] #инициализировать список p с одним пустым элементом. так надо.
for i in range (0, len(s)): #для индекса i, изменяющегося на отрезке от нуля до значения функции len(s), равной количеству строк списка
if s[i] in p: #если элемент списка s с индексом i присутствует в списке p...
continue #...то пропускаем его и выполняем следующий прогон цикла
else: #в противном случае:
p.append(s[i]) #добавляем к списку p элемент списка s с индексом i
ro.writelines(p) #построчно выписать список p в файл ro
ri.close() #закрыть исходный файл
ro.close() #закрыть выходной файл