简体   繁体   English

Writelines 写入没有换行符的行,只填充文件

[英]Writelines writes lines without newline, Just fills the file

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 = "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)

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, eg, by using the csv module 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.无论您使用的是简单写入还是csv.writer ,它都会让您的生活更简单,并且您的代码更易于阅读。 (Sometimes there can be simplicity, efficiency, or correctness reasons to write a file all at once—but once you've moved the open all the way to the opposite end of the program from the write , you've pretty much lost any benefits of all-at-once.) (有时可能出于简单、效率或正确性的原因而一次性写入一个文件——但是一旦您将openwrite一直移动到程序的另一端,您几乎失去了任何好处一次完成。)

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

As others have noted, writelines is 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)

writelines() does not add line separators. writelines()不添加行分隔符。 You can alter the list of strings by using map() to add a new \\n (line break) at the end of each string.您可以通过使用map() ) 在每个字符串的末尾添加一个新的\\n (换行符map()来更改字符串列表。

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

As others have mentioned, and counter to what the method name would imply, writelines does not add line separators.正如其他人所提到的,与方法名称所暗示的writelineswritelines不添加行分隔符。 This is a textbook case for a generator.这是发电机的教科书案例。 Here is a contrived example:这是一个人为的例子:

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. IO(写入文件)是这种事情实际上很重要的时候。 Hope this helps someone!希望这可以帮助某人!

Credits to Brent Faust .归功于Brent Faust


Python >= 3.6 with format string: Python >= 3.6 格式字符串:

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

lines can be a set . lines可以是一个set

If you are oldschool (like me) you may add f.write('\\n') below the second line.如果您是老派(像我一样),您可以在第二行下方添加f.write('\\n')

As we have well established here, writelines does not append the newlines for you.正如我们在此处建立的那样, writelines不会为您附加换行符。 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!但是,每个人似乎都缺少的是,它在用作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!当您以二进制模式(通过'rb' )打开文件进行读取时,然后使用readlines()将文件内容提取到内存中,按行拆分,换行符保持附加到行尾! So, if you then subsequently write them back, you don't likely want writelines to append anything!因此,如果您随后将它们写回,您可能不希望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.您应该以与开始时相同的文件内容结束。

As we want to only separate lines, and the writelines function in python does not support adding separator between lines, I have written the simple code below which best suits this problem:由于我们只想分隔行,而python中的writelines函数不支持writelines之间添加分隔符,因此我编写了以下最适合此问题的简单代码:

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

and finally:最后:

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

and you are done.你就完成了。

当我试图在R中写入文件时解决类似的问题时,我一直停留在这个线程上。所以对于那些遇到相同问题的人,这是我的解决方案:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM