writelines
file handling
python
no newline
text files

Writelines writes lines without newline, Just fills the file

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Python's writelines() method writes a sequence of strings to a file without adding newline characters between them. Unlike what the name suggests, writelines() does not write separate "lines" — it writes each string exactly as-is, concatenated together. If you want each string on its own line, you must include \n in each string yourself. This is a deliberate design choice: writelines() is the inverse of readlines(), which preserves the newline characters already present in each line.

The Problem

python
1lines = ["First line", "Second line", "Third line"]
2
3with open("output.txt", "w") as f:
4    f.writelines(lines)
5
6# output.txt contains:
7# First lineSecond lineThird line

All three strings are concatenated into a single line because none of them contain a newline character.

The Fix: Add Newlines to Each String

python
1lines = ["First line", "Second line", "Third line"]
2
3# Option 1: Add \n to each string
4with open("output.txt", "w") as f:
5    f.writelines(line + "\n" for line in lines)
6
7# Option 2: Include \n in the list
8lines_with_newlines = ["First line\n", "Second line\n", "Third line\n"]
9with open("output.txt", "w") as f:
10    f.writelines(lines_with_newlines)
11
12# Option 3: Use join and write
13with open("output.txt", "w") as f:
14    f.write("\n".join(lines) + "\n")
15
16# All produce:
17# First line
18# Second line
19# Third line

Why writelines() Works This Way

writelines() is designed as the counterpart to readlines(). When you read a file with readlines(), each line already includes its trailing \n:

python
1# Read a file
2with open("input.txt", "r") as f:
3    lines = f.readlines()
4    # lines = ["First line\n", "Second line\n", "Third line\n"]
5
6# Write it back — works perfectly because \n is preserved
7with open("output.txt", "w") as f:
8    f.writelines(lines)

The symmetry between readlines() and writelines() means data round-trips correctly without adding or removing newlines.

writelines() vs write() vs print()

python
1lines = ["apple", "banana", "cherry"]
2
3# writelines: no newlines added, writes iterable of strings
4with open("out1.txt", "w") as f:
5    f.writelines(lines)
6# applebananaCherry
7
8# write: writes a single string, no newline added
9with open("out2.txt", "w") as f:
10    f.write("apple")
11    f.write("banana")
12# applebanana
13
14# print: adds newline by default, can redirect to file
15with open("out3.txt", "w") as f:
16    for line in lines:
17        print(line, file=f)
18# apple
19# banana
20# cherry
21
22# print with custom separator
23with open("out4.txt", "w") as f:
24    print(*lines, sep="\n", file=f)
25# apple
26# banana
27# cherry

print() adds a newline by default (controlled by the end parameter), making it the simplest option for writing lines to a file.

Writing Lines with a Loop

For more control, use a loop with write():

python
1lines = ["First line", "Second line", "Third line"]
2
3with open("output.txt", "w") as f:
4    for line in lines:
5        f.write(line + "\n")
6
7# Or with formatted strings
8data = [("Alice", 30), ("Bob", 25), ("Charlie", 35)]
9
10with open("output.csv", "w") as f:
11    f.write("name,age\n")
12    for name, age in data:
13        f.write(f"{name},{age}\n")

Performance Comparison

python
1import time
2
3lines = [f"Line {i}" for i in range(1_000_000)]
4
5# writelines with generator — memory efficient
6start = time.time()
7with open("out.txt", "w") as f:
8    f.writelines(line + "\n" for line in lines)
9print(f"writelines: {time.time() - start:.3f}s")
10
11# write in a loop
12start = time.time()
13with open("out.txt", "w") as f:
14    for line in lines:
15        f.write(line + "\n")
16print(f"write loop: {time.time() - start:.3f}s")
17
18# join then write — fastest but uses more memory
19start = time.time()
20with open("out.txt", "w") as f:
21    f.write("\n".join(lines) + "\n")
22print(f"join+write: {time.time() - start:.3f}s")

For large files, "\n".join(lines) is typically fastest because it makes a single system call, but it requires all data in memory at once. writelines() with a generator is the most memory-efficient approach.

Writing Binary Files

writelines() also works with binary files, but uses bytes instead of str:

python
1# Binary mode
2with open("output.bin", "wb") as f:
3    f.writelines([b"\x00\x01\x02", b"\x03\x04\x05"])
4# File contains: 00 01 02 03 04 05 (no separator)
5
6# Text mode with encoding
7with open("output_utf8.txt", "w", encoding="utf-8") as f:
8    f.writelines(["Héllo\n", "Wörld\n"])

Common Pitfalls

  • Assuming writelines() adds newlines: The name is misleading. writelines() does not add any separator between strings. It writes each string exactly as provided. Always include \n in each string if you want separate lines.
  • Passing a single string instead of an iterable: writelines("hello") writes each character individually (h, e, l, l, o) because a string is iterable. This works but is confusing — use write("hello") for single strings.
  • Double newlines from readlines() + manual \n: If you read lines with readlines() (which preserves \n) and then add another \n before writing, each line gets a blank line between it. Check whether your strings already end with \n before adding more.
  • Memory issues with large join() operations: "\n".join(million_lines) creates a single huge string in memory. For very large files, use writelines() with a generator expression to write incrementally without buffering everything.
  • Forgetting the final newline: POSIX convention expects files to end with a newline. Using "\n".join(lines) without adding a trailing \n produces a file where the last line has no newline, which can cause issues with tools like wc -l that expect it.

Summary

  • writelines() writes strings exactly as given — it does not add newlines between them
  • Add \n to each string yourself: f.writelines(line + "\n" for line in lines)
  • writelines() is the inverse of readlines(), which preserves trailing \n characters
  • For simple line-by-line writing, print(line, file=f) is the easiest approach
  • For large files, writelines() with a generator is the most memory-efficient
  • "\n".join(lines) with a single write() is fastest but uses more memory

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.