Python Writelines不使用换行符写入行,只填充文件

Python Writelines不使用换行符写入行,只填充文件,python,Python,我有一个将列表写入文件的程序。 该列表是管道分隔线的列表,这些线应按如下方式写入文件: 123|GSV|Weather_Mean|hello|joe|43.45 122|GEV|temp_Mean|hello|joe|23.45 124|GSI|Weather_Mean|hello|Mike|47.45 但它给他们写了这样一行啊哈: 123|GSV|Weather_Mean|hello|joe|43.45122|GEV|temp_Mean|hello|joe|23.45124|GSI|Weat

我有一个将列表写入文件的程序。 该列表是管道分隔线的列表,这些线应按如下方式写入文件:

123|GSV|Weather_Mean|hello|joe|43.45
122|GEV|temp_Mean|hello|joe|23.45
124|GSI|Weather_Mean|hello|Mike|47.45
但它给他们写了这样一行啊哈:

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 = "Dummy@dummy.com"
    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)
各国:

writelines()
不添加行分隔符

因此,您需要自己添加它们。例如:

    line_list.append(new_line + "\n")

每当您将一个新项目添加到
line\u列表中时,对于Python新手来说,这实际上是一个非常常见的问题,尤其是在标准库和流行的第三方库中,一些读取函数去掉了换行符,但几乎没有任何写入函数(除了与
log
相关的东西)添加它们

因此,有很多Python代码可以执行以下操作:

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

任何一个都是正确的,当然,你甚至可以用换行符函数来编写你自己的WriteLines来完成它

但你只有在无法避免的情况下才应该这样做

如果你能像Greg Hewgill的建议那样首先创建/保留新行,那就更好了:

line_list.append(new_line + "\n")
如果你能在比原始文本行更高的层次上工作,那就更好了,比如像esuaro建议的那样,使用标准库中的模块

例如,在定义
fw
之后,您可以执行以下操作:

cw = csv.writer(fw, delimiter='|')
然后,与此相反:

new_line = d[looking_for]+'|'+'|'.join(columns[1:])
line_list.append(new_line)
fw.writelines(line_list)
您可以这样做:

row_list.append(d[looking_for] + columns[1:])
cw.writerows(row_list)
最后,与此相反:

new_line = d[looking_for]+'|'+'|'.join(columns[1:])
line_list.append(new_line)
fw.writelines(line_list)
您可以这样做:

row_list.append(d[looking_for] + columns[1:])
cw.writerows(row_list)
最后,您的设计是“打开一个文件,然后建立一个要添加到文件的行列表,然后一次写入所有行”。如果你要在上面打开文件,为什么不一行一行地写呢?无论您使用的是简单的书写还是
csv.writer
,它都会使您的生活更简单,代码更易于阅读。(有时一次编写一个文件可能有简单、高效或正确的理由,但一旦您将
打开的
写入一直移动到程序的另一端,您几乎一次就失去了所有好处。)

写线()
不添加行分隔符。您可以通过使用
map()
在每个字符串的末尾添加新的
\n
(换行符)来更改字符串列表

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

正如其他人所提到的,与方法名称的含义相反,
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(写入文件)是指这种事情实际上很重要的时候。希望这对别人有帮助

正如其他人所指出的,
writelines
是一个用词不当的词(它可笑地没有在每行末尾添加换行符)

为此,请将其显式添加到每行:

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

正如我们在这里所确定的,
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)

您应该得到与开始时相同的文件内容。

因为我们只想分隔行,而python中的
writelines
函数不支持在行之间添加分隔符,因此我编写了以下最适合此问题的简单代码:

sep = "\n" # defining the separator
new_lines = sep.join(lines) # lines as an iterator containing line strings
最后:

with open("file_name", 'w') as file:
    file.writelines(new_lines)

你完成了。

归功于布伦特·浮士德


Python>=3.6,带格式字符串:

with open(dst_filename, 'w') as f:
    f.writelines(f'{s}\n' for s in lines)
可以是


如果你是老派(和我一样),你可以在第二行下面添加
f.write('\n')

你似乎没有在
行列表中的任何地方添加
“\n”
。你可以看看我在哪里添加“\n”?是否将其添加到列表对象???+1。这是最简单的解决方案,如果OP不想切换到更高的级别,如
csv
,几乎可以肯定这是最合适的。仅仅为了“匹配”,函数的名称就太糟糕了readlines.bether-than糟糕的名称:糟糕的功能所有这一切都是因为python在
writelines
Wow中没有明显的作用。对于Python来说,这是一种荒谬的行为:readlines()应该去掉换行符,但不会,writelines()应该添加换行符,但不会。拥有读线和写线的全部意义在于,您可以轻松地读写列表。有点恼火!像f.writelines(lines,end='\n')这样的PEP值吗?在第二个示例中,应该是fw.writelines(line+'\n'表示line in line_list)在第二个示例中,什么时候您希望读取一个文件以将其写回?您对代码示例的理解太过字面化了。我并没有包括一个虚假的上下文和无关的示例代码,当您读取一个文件并将其写回时。在这两者之间通常会有一些东西,您可以在其中修改内容。或者,您可能正在将源文件“复制”/调整为目标文件。重点是读/写行的对应方会隐式地处理这个问题。对不起,我不是故意要坚持这个问题。只是大多数时候,当我读一个文件和wri的时候