How to Write Multiple Lines to a File in Python

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'
Command Prompt output showing Python writelines writing ChicagoHoustonPhoenix on one line without newlines and on separate lines when newline characters are added
Without "\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}
MethodAdds newlines?Best for
f.write(line + "\n") in a loopNo, add themLines produced one at a time
f.writelines(iterable)No, add themA list or generator of strings
print(line, file=f)YesMixing values of any type, like console output
Path(...).write_text(text)No, add themWriting 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
Command Prompt output of TypeError write() argument must be str, not int when writelines gets numbers, and the fixed version writing one score per line
Convert values with an f-string (or 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'
Command Prompt output comparing raw bytes of a file written in Windows text mode with CRLF line endings and one written with newline='\n'
The raw bytes show \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
Command Prompt running a Python program where the user types three notes, presses Enter on an empty line, and the notes are written to notes.txt
Lines typed at the keyboard, written to a file and read back.

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 csv module 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:

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.