Строка outfile = open(output_file, "w")
усекает ваш файл, что бы вы ни делали.Последующие чтения найдут пустой файл.Моя рекомендация сделать это безопасно - использовать временный файл:
- Открыть временный файл для записи
- Обрабатывать ввод для нового вывода
- Закрыть оба файла
- Переместить временный файл к имени входного файла
Это гораздо надежнее, чем дважды открыть файл для чтения и записи.Если что-то пойдет не так, у вас будет оригинал и все, что вы делали до сих пор.Ваш текущий подход может испортить ваш файл, если что-то пойдет не так в процессе.
Вот пример использования tempfile.NamedTemporaryFile
и блока with
, чтобы убедиться, что все закрыто правильно, даже в случае ошибки:
from tempfile import NamedTemporaryFile
from shutil import move
input_file = "input.txt"
output_file = "input.txt"
seen_lines = set()
with NamedTemporaryFile('w', delete=False) as output, open(input_file) as input:
for line in open(input_file, "r"):
sline = line.rstrip('\n')
if sline not in seen_lines:
output.write(line)
seen_lines.add(sline)
move(output.name, output_file)
move
в конце будет работать правильно, даже если имена входа и выхода совпадают, поскольку output.name
гарантированно будет отличаться от обоих.
Обратите внимание, что я убираю новую строку из каждой строки в наборе, поскольку последняя строка может не иметь ее.
Альтернативное решение
Если вам не важен порядок строк, вы можете несколько упростить процесс, выполнив все непосредственно в памяти:
input_file = "input.txt"
output_file = "input.txt"
with open(input_file) as input:
unique = set(line.rstrip('\n') for line in input)
with open(output_file, 'w') as output:
for line in unique:
output.write(line)
output.write('\n')
Вы можете сравнить это с
with open(input_file) as input:
unique = set(line.rstrip('\n') for line in input.readlines())
with open(output_file, 'w') as output:
output.write('\n'.join(unique))
Вторая версия делает то же самое, но загружает и записывает все сразу.