Why can't I use a string for a new line in write (), but can I use it in writelines ()?
The idea is this: if you want to write a single line, you can do this with write() . If you have a sequence of strings, you can write them all using writelines() .
write(arg) expects a string as an argument and writes it to a file. If you provide a list of strings, this will throw an exception (by the way, show us the errors!).
writelines(arg) expects iterability as an argument (the iterable object can be a tuple, list, string, or iterator in the most general sense). Each element contained in the iterator is expected to be a string. The tuple of strings is what you provided, so it worked.
The nature of the string (s) does not matter for both functions, i.e. they simply write to the file everything that you provide them. The interesting part is that writelines() does not add newline characters on its own, so the method name can be quite confusing. It really behaves like an imaginary method called write_all_of_these_strings(sequence) .
The following is an idiomatic way in Python to write a list of lines to a file, saving each line in its own line:
lines = ['line1', 'line2'] with open('filename.txt', 'w') as f: f.write('\n'.join(lines))
This will help you close the file. The '\n'.join(lines) construct concatenates (connects) the lines in the lines list and uses the "\ n" character as glue. This is more efficient than using the + operator.
Starting with the same sequence of lines , ending with the same output, but using writelines() :
lines = ['line1', 'line2'] with open('filename.txt', 'w') as f: f.writelines("%s\n" % l for l in lines)
This uses a generator expression and dynamically creates strings with trailing string expansion. writelines() over this sequence of lines and writes each item.
Edit: Another point you should be aware of:
write() and readlines() existed before writing writelines() . writelines() was introduced later as an analogue of readlines() , so that it was easy to write the contents of a file that was simply read through readlines() :
outfile.writelines(infile.readlines())
Indeed, this is the main reason why writelines has such a confusing name. In addition, today we no longer want to use this method. readlines() reads the entire file into your computer's memory before writelines() starts writing data. First of all, it can waste time. Why not start writing pieces of data while reading other pieces? But, most importantly, this approach can be very memory intensive. In extreme cases, when the input file is larger than the memory of your computer, this approach does not even work. The solution to this problem is to use only iterators. Working example:
with open('inputfile') as infile: with open('outputfile') as outfile: for line in infile: outfile.write(line)
This reads the input file line by line. As soon as one line is read, this line is written to the output file. From the point of view of the scheme, there is always only one line in memory (compared to all the contents of the file in memory in the case of the readlines / writelines approach).