To write multiple lines to a file in Python, open the file with open("file.txt", "w") and call f.write("\n".join(lines) + "\n"), or f.writelines() with each line ending in "\n". writelines() does not add line breaks for you, which is the most common surprise. This guide compares write(), writelines(), print(file=...) and pathlib, shows how to append lines, write numbers, handle newlines on Windows, and save lines typed by a user.
All examples were run with Python 3.12.5 in the Windows Command Prompt. Reference: Reading and writing files and IOBase.writelines() in the Python docs.
Write multiple lines at once
lines = ["Order 1001: shipped", "Order 1002: packed", "Order 1003: pending"]
with open("orders.txt", "w", encoding="utf-8") as f:
f.write("\n".join(lines) + "\n") # one call, a newline after every line
with open("orders.txt", encoding="utf-8") as f:
print(f.read())
Output:
Order 1001: shipped
Order 1002: packed
Order 1003: pending
The with block closes the file automatically, so the data is saved even if an error happens later. Mode "w" creates the file or replaces its contents.
writelines() does not add newlines
writelines() writes each string exactly as it is. If the strings do not end with \n, everything ends up on one line:
cities = ["Chicago", "Houston", "Phoenix"]
with open("no_newlines.txt", "w") as f:
f.writelines(cities) # writelines does NOT add newlines
with open("with_newlines.txt", "w") as f:
f.writelines(city + "\n" for city in cities) # add them yourself
print(repr(open("no_newlines.txt").read()))
print(repr(open("with_newlines.txt").read()))
Output:
'ChicagoHoustonPhoenix'
'Chicago\nHouston\nPhoenix\n'
"\n" the lines run together.So to answer a common quiz question: both write() and writelines() can write multiple lines, but writelines() is the method that takes a list (or any iterable) of strings in one call.
Four ways to write lines to a file
rows = ["id,name,score", "1,Anna,91", "2,Ben,78"]
with open("a.txt", "w") as f: # 1. write() in a loop
for row in rows:
f.write(row + "\n")
with open("b.txt", "w") as f: # 2. writelines() with a generator
f.writelines(f"{row}\n" for row in rows)
with open("c.txt", "w") as f: # 3. print() to a file adds the newline for you
for row in rows:
print(row, file=f)
from pathlib import Path # 4. pathlib: one line for the whole file
Path("d.txt").write_text("\n".join(rows) + "\n")
print({name: open(name).read() == open("a.txt").read() for name in ["b.txt", "c.txt", "d.txt"]})
Output:
{'b.txt': True, 'c.txt': True, 'd.txt': True}
| Method | Adds newlines? | Best for |
|---|---|---|
f.write(line + "\n") in a loop | No, add them | Lines produced one at a time |
f.writelines(iterable) | No, add them | A list or generator of strings |
print(line, file=f) | Yes | Mixing values of any type, like console output |
Path(...).write_text(text) | No, add them | Writing a whole small file in one line |
TypeError: write() argument must be str, not int
Files opened in text mode accept only strings. Writing numbers directly fails:
scores = [91, 78, 85]
try:
with open("scores.txt", "w") as f:
f.writelines(scores) # numbers, not strings
except TypeError as e:
print("TypeError:", e)
with open("scores.txt", "w") as f:
f.writelines(f"{s}\n" for s in scores) # convert each value to a string
print(open("scores.txt").read())
Output:
TypeError: write() argument must be str, not int
91
78
85
str()) before writing.Newlines on Windows: \n becomes \r\n
In text mode Python translates \n into the operating system’s line ending when writing. On Windows that is \r\n, so the file is larger than the text you wrote. Pass newline="\n" when you need Unix line endings (for scripts, CSV files for Linux servers, or Git repositories):
lines = ["first", "second", "third"]
with open("text_mode.txt", "w") as f: # text mode on Windows
f.write("\n".join(lines) + "\n")
with open("unix_endings.txt", "w", newline="\n") as f: # keep \n exactly
f.write("\n".join(lines) + "\n")
for name in ["text_mode.txt", "unix_endings.txt"]:
data = open(name, "rb").read() # read the raw bytes
print(f"{name:<17} {len(data)} bytes {data!r}")
Output:
text_mode.txt 22 bytes b'first\r\nsecond\r\nthird\r\n'
unix_endings.txt 19 bytes b'first\nsecond\nthird\n'
\r\n in text mode on Windows.You always write \n in your code; do not add \r yourself, or you get \r\r\n on Windows.
Append lines to an existing file
Mode "a" keeps the current contents and writes at the end:
from datetime import date
with open("log.txt", "w") as f:
f.write("log started\n")
for event in ["backup done", "report sent"]:
with open("log.txt", "a") as f: # "a" adds to the end instead of replacing the file
f.write(f"{date(2025, 7, 4)} {event}\n")
print(open("log.txt").read())
Output:
log started
2025-07-04 backup done
2025-07-04 report sent
Save lines typed by the user
print("Type your notes, one per line. Press Enter on an empty line to finish.")
notes = []
while True:
line = input("> ")
if not line:
break
notes.append(line)
with open("notes.txt", "w", encoding="utf-8") as f:
f.writelines(note + "\n" for note in notes)
print(f"Saved {len(notes)} lines to notes.txt:")
print(open("notes.txt", encoding="utf-8").read())
Output (the user typed three notes and then an empty line):
Type your notes, one per line. Press Enter on an empty line to finish.
> buy milk
> call Sam
> submit report
>
Saved 3 lines to notes.txt:
buy milk
call Sam
submit report
Tips
- Always pass
encoding="utf-8"when the text can contain non-English characters; the Windows default encoding is not UTF-8 in older Python versions. - Use
"x"mode to create a new file and fail if it already exists, so you never overwrite data by accident. - For CSV data, the
csvmodule handles quoting and commas inside values for you. - Writing many small pieces is fine: Python buffers the output and writes it to disk in blocks.
More Python file and string tutorials:
- Remove characters from a string in Python
- Append to a string in Python
- Get the file size in Python
- Convert a string to float in Python
Frequently asked questions
How do I write multiple lines to a file in Python?
Open the file in "w" mode and call f.write("\n".join(lines) + "\n"), or f.writelines(line + "\n" for line in lines).
Does writelines add a newline?
No. writelines() writes each string exactly as given, so add "\n" to every line yourself.
What is the difference between write and writelines?
write() takes one string; writelines() takes an iterable of strings and writes them one after another. Neither adds newlines.
How do I write a list to a file line by line?
Loop and write f"{item}\n" for each item, or use print(item, file=f), which converts values to strings and adds the newline.
How do I add lines to an existing file without deleting it?
Open it in append mode: open("file.txt", "a").
Why do my lines end with \r\n on Windows?
Text mode converts \n to the Windows line ending \r\n. Open the file with newline="\n" to keep \n.
Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn