Python Writelines 写入没有换行符的行,只填充文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13730107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Writelines writes lines without newline, Just fills the file
提问by user836087
I have a program that writes a list to a file. The list is a list of pipe delimited lines and the lines should be written to the file like this:
我有一个将列表写入文件的程序。该列表是由管道分隔的行的列表,这些行应该像这样写入文件:
123|GSV|Weather_Mean|hello|joe|43.45
122|GEV|temp_Mean|hello|joe|23.45
124|GSI|Weather_Mean|hello|Mike|47.45
BUT it wrote them line this ahhhh:
但它写了他们这行啊啊:
123|GSV|Weather_Mean|hello|joe|43.45122|GEV|temp_Mean|hello|joe|23.45124|GSI|Weather_Mean|hello|Mike|47.45
This program wrote all the lines into like one line without any line breaks.. This hurts me a lot and I gotta figure-out how to reverse this but anyway, where is my program wrong here? I thought write lines should write lines down the file rather than just write everything to one line..
这个程序把所有的行都写成一行,没有任何换行符。我认为写行应该在文件中写下行,而不是将所有内容都写到一行中。
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)
采纳答案by abarnert
This is actually a pretty common problem for newcomers to Python—especially since, across the standard library and popular third-party libraries, some reading functions strip out newlines, but almost no writing functions (except the log-related stuff) add them.
对于 Python 新手来说,这实际上是一个非常普遍的问题——尤其是因为,在标准库和流行的第三方库中,一些读取函数会去掉换行符,但几乎没有写入函数(除了 -log相关的东西)添加它们。
So, there's a lot of Python code out there that does things like:
因此,有很多 Python 代码可以执行以下操作:
fw.write('\n'.join(line_list) + '\n')
or
或者
fw.write(line + '\n' for line in line_list)
Either one is correct, and of course you could even write your own writelinesWithNewlines function that wraps it up…
任何一个都是正确的,当然你甚至可以编写自己的 writelinesWithNewlines 函数来包装它......
But you should only do this if you can't avoid it.
但是,只有在无法避免的情况下才应该这样做。
It's better if you can create/keep the newlines in the first place—as in Greg Hewgill's suggestions:
如果您可以首先创建/保留换行符会更好 - 正如 Greg Hewgill 的建议:
line_list.append(new_line + "\n")
And it's even better if you can work at a higher level than raw lines of text, e.g., by using the csvmodule in the standard library, as esuaro suggests.
如果您可以在比原始文本行更高的级别上工作,那就更好了,例如,如 esuaro 建议的那样,通过使用标准库中的csv模块。
For example, right after defining fw, you might do this:
例如,在定义之后fw,您可以执行以下操作:
cw = csv.writer(fw, delimiter='|')
Then, instead of this:
然后,而不是这样:
new_line = d[looking_for]+'|'+'|'.join(columns[1:])
line_list.append(new_line)
You do this:
你做这个:
row_list.append(d[looking_for] + columns[1:])
And at the end, instead of this:
最后,而不是这样:
fw.writelines(line_list)
You do this:
你做这个:
cw.writerows(row_list)
Finally, your design is "open a file, then build up a list of lines to add to the file, then write them all at once". If you're going to open the file up top, why not just write the lines one by one? Whether you're using simple writes or a csv.writer, it'll make your life simpler, and your code easier to read. (Sometimes there can be simplicity, efficiency, or correctness reasons to write a file all at once—but once you've moved the openall the way to the opposite end of the program from the write, you've pretty much lost any benefits of all-at-once.)
最后,您的设计是“打开一个文件,然后建立一个要添加到文件中的行列表,然后一次性写入所有行”。如果您要打开文件顶部,为什么不一行一行地写?无论您使用简单的写入还是使用csv.writer,它都会让您的生活更简单,并且您的代码更易于阅读。(有时可以有简单,有效,或正确性的理由写一个文件一次全部,但一旦你移动了open所有的方式,从程序的另一端write,你已经几乎失去了所有的任何利益- 一次。)
回答by Greg Hewgill
The documentation for writelines()states:
状态的文档writelines():
writelines()does not add line separators
writelines()不添加行分隔符
So you'll need to add them yourself. For example:
所以你需要自己添加它们。例如:
line_list.append(new_line + "\n")
whenever you append a new item to line_list.
每当您将新项目附加到line_list.
回答by Docuemada
I kept ending up on this thread when looking to solve a similar problem when writing to files in R. So for those who have had the same issue, here is my solution:
当我在 R 中写入文件时希望解决类似问题时,我一直在这个线程上结束。所以对于那些遇到同样问题的人,这是我的解决方案:
List_To_Be_Written_To_File<-sprintf("%s%s",as.character(List_To_Be_Written_To_File),"\n")
回答by Jossef Harush
writelines()does not add line separators. You can alter the list of strings by using map()to add a new \n(line break) at the end of each string.
writelines()不添加行分隔符。您可以通过在每个字符串的末尾map()添加一个新的\n(换行符)来更改字符串列表。
items = ['abc', '123', '!@#']
items = map(lambda x: x + '\n', items)
w.writelines(items)
回答by jtschoonhoven
As others have mentioned, and counter to what the method name would imply, writelinesdoes not add line separators. This is a textbook case for a generator. Here is a contrived example:
正如其他人所提到的,与方法名称所暗示的相反,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))
Benefits: adds newlines explicitly without modifying the input or output values or doing any messy string concatenation. And, critically, does not create any new data structures in memory. IO (writing to a file) is when that kind of thing tends to actually matter. Hope this helps someone!
优点:显式添加换行符而不修改输入或输出值或进行任何混乱的字符串连接。而且,关键的是,它不会在内存中创建任何新的数据结构。IO(写入文件)是这种事情实际上很重要的时候。希望这可以帮助某人!
回答by Brent Faust
As others have noted, writelinesis a misnomer (it ridiculously does not add newlines to the end of each line).
正如其他人所指出的那样,writelines是用词不当(可笑的是,它没有在每行的末尾添加换行符)。
To do that, explicitly add it to each line:
为此,请将其显式添加到每一行:
with open(dst_filename, 'w') as f:
f.writelines(s + '\n' for s in lines)
回答by BuvinJ
As we have well established here, writelinesdoes not append the newlines for you. But, what everyone seems to be missing, is that it doesn't have to when used as a direct "counterpart" for readlines()and the initial read persevered the newlines!
正如我们在此处建立的那样,writelines不会为您附加换行符。但是,每个人似乎都缺少的是,当用作直接的“对应物”时,它没有必要,readlines()并且最初的阅读坚持换行!
When you open a file for reading in binary mode(via 'rb'), then use readlines()to fetch the file contents into memory, split by line, the newlines remain attached to the end of your lines! So, if you then subsequently write them back, you don't likely want writelinesto append anything!
当您以二进制模式(通过'rb')打开文件进行读取时,然后用于readlines()将文件内容提取到内存中,按行拆分,换行符保持附加到行尾!因此,如果您随后将它们写回,您可能不想writelines附加任何内容!
So if, you do something like:
因此,如果您执行以下操作:
with open('test.txt','rb') as f: lines=f.readlines()
with open('test.txt','wb') as f: f.writelines(lines)
You should end up with the same file content you started with.
您应该以与开始时相同的文件内容结束。

