Подтвердить что ты не робот

Writelines пишет строки без перевода строки, просто заполняет файл

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

123|GSV|Weather_Mean|hello|joe|43.45
122|GEV|temp_Mean|hello|joe|23.45
124|GSI|Weather_Mean|hello|Mike|47.45

НО он написал им строку this ahhhh:

123|GSV|Weather_Mean|hello|joe|43.45122|GEV|temp_Mean|hello|joe|23.45124|GSI|Weather_Mean|hello|Mike|47.45

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

fr = open(sys.argv[1], 'r') # source file
fw = open(sys.argv[2]+"/masked_"+sys.argv[1], 'w') # Target Directory Location

for line in fr:
    line = line.strip()
    if line == "":
        continue
    columns = line.strip().split('|')
    if columns[0].find("@") > 1:
        looking_for = columns[0] # this is what we need to search
    else:
        looking_for = "[email protected]"
    if looking_for in d:
        # by default, iterating over a dictionary will return keys
            new_line = d[looking_for]+'|'+'|'.join(columns[1:])
            line_list.append(new_line)
    else:
        new_idx = str(len(d)+1)
        d[looking_for] = new_idx
        kv = open(sys.argv[3], 'a')
        kv.write(looking_for+" "+new_idx+'\n')
        kv.close()
        new_line = d[looking_for]+'|'+'|'.join(columns[1:])
        line_list.append(new_line)
fw.writelines(line_list)
4b9b3361

Ответ 1

Это на самом деле довольно распространенная проблема для новичков в Python, особенно потому, что через стандартную библиотеку и популярные сторонние библиотеки некоторые функции чтения вычеркивают символы новой строки, но почти не имеют функций записи (кроме связанных с log) добавьте их.

Итак, там много кода Python, который делает такие вещи, как:

fw.write('\n'.join(line_list) + '\n')

или

fw.write(line + '\n' for line in line_list)

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

Но вы должны делать это только в том случае, если не можете этого избежать.

Лучше, если вы можете создать/сохранить новые строки в первую очередь - как в предложениях Грега Хьюглилла:

line_list.append(new_line + "\n")

И это даже лучше, если вы можете работать на более высоком уровне, чем исходные строки текста, например, используя csv модуль в стандартная библиотека, как предполагает esuaro.

Например, сразу после определения fw вы можете сделать это:

cw = csv.writer(fw, delimiter='|')

Затем вместо этого:

new_line = d[looking_for]+'|'+'|'.join(columns[1:])
line_list.append(new_line)

Вы делаете это:

row_list.append(d[looking_for] + columns[1:])

И в конце вместо этого:

fw.writelines(line_list)

Вы делаете это:

cw.writerows(row_list)

Наконец, ваш проект "открыть файл, а затем создать список строк для добавления в файл, а затем написать их все сразу". Если вы собираетесь открыть файл вверх, почему бы просто не писать строки один за другим? Если вы используете простые записи или csv.writer, это упростит вашу жизнь, и ваш код будет легче читать. (Иногда может быть простота, эффективность или правильность, чтобы написать файл все сразу - но как только вы переместили open полностью на противоположный конец программы из write, вы довольно многое потеряло все преимущества "все-в-одном".)

Ответ 2

Документация для writelines() гласит:

writelines() не добавляет разделители строк

Итак, вам нужно добавить их самостоятельно. Например:

    line_list.append(new_line + "\n")

всякий раз, когда вы добавляете новый элемент в line_list.

Ответ 3

writelines() не добавляет разделителей строк. Вы можете изменить список строк, используя map(), чтобы добавить новый \n (разрыв строки) в конце каждой строки.

items = ['abc', '123', '[email protected]#']
items = map(lambda x: x + '\n', items)
w.writelines(items)

Ответ 4

Как уже отмечали другие, writelines - это неправильно (это нелепо не добавляет новые строки в конце каждой строки).

Для этого используйте карту:

with open(dst_filename, 'w') as f:
    f.writelines(map(lambda s: s + '\n', lines))

Ответ 5

Как уже упоминалось, и противоречит тому, что подразумевалось в имени метода, writelines не добавляет разделители строк. Это случай учебника для генератора. Вот надуманный пример:

def item_generator(things):
    for item in things:
        yield item
        yield '\n'

def write_things_to_file(things):
    with open('path_to_file.txt', 'wb') as f:
        f.writelines(item_generator(things))

Преимущества: добавляет новые строки явно, не изменяя значения ввода или вывода или не создавая беспорядочную конкатенацию строк. И, критически, не создает никаких новых структур данных в памяти. IO (запись в файл) - это когда такая вещь имеет значение. Надеюсь, это поможет кому-то!

Ответ 6

Как мы здесь хорошо зарекомендовали себя, writelines не добавляет writelines строки для вас. Но то, что всем, похоже, не хватает, так это то, что это не обязательно, когда используется в качестве прямого "аналога" для readlines() а начальное чтение сохранило символы новой строки!

Когда вы открываете файл для чтения в двоичном режиме (через 'rb'), а затем используете readlines() для извлечения содержимого файла в память, разделенные на строки, новые строки остаются прикрепленными к концу ваших строк! Таким образом, если вы впоследствии напишете их обратно, вы вряд ли захотите, чтобы writelines добавляли!

Так что, если вы делаете что-то вроде:

with open('test.txt','rb') as f: lines=f.readlines()
with open('test.txt','wb') as f: f.writelines(lines)

Вы должны получить тот же самый файл, с которым вы начали.

Ответ 7

Я продолжал заканчивать эту тему, когда искал решение подобной проблемы при записи файлов в R. Итак, для тех, у кого была такая же проблема, вот мое решение:

List_To_Be_Written_To_File<-sprintf("%s%s",as.character(List_To_Be_Written_To_File),"\n")