Skip to main content

Python File Writing: write() and writelines() Methods

Writing data to files is a fundamental skill in Python programming. Whether you're saving user data, logging events, generating reports, or creating any text-based output, Python's .write() and .writelines() methods handle the task. Understanding both methods and their critical difference—neither automatically adds newlines—is essential for correct file operations.

Key Takeaways

  • .write() writes a single string; .writelines() writes multiple strings from an iterable
  • Neither method automatically adds newlines (\n)—you must include them explicitly
  • Use 'w' mode to overwrite files; use 'a' mode to append
  • .writelines() is more efficient for pre-built lists of strings
  • Always use the with statement to ensure files close automatically

Understanding file.write(): Writing a Single String

The .write() method is the fundamental way to write data. It accepts a single string and writes it to the file. After writing, it returns the number of characters written.

Critical Detail: No Automatic Newlines

The .write() method does not automatically add a newline character (\n) at the end of the string. If you want your text on separate lines, you must explicitly include \n in the string.

# write_example.py

# 'w' mode: creates the file or overwrites it if it exists
with open('report.txt', 'w') as f:
f.write("Sales Report\n")
f.write("============\n")
f.write("January: $1500\n")
f.write("February: $1200\n")
f.write("March: $1800\n")

print("'report.txt' has been generated.")

When you open report.txt, you see properly formatted output:

Sales Report
============
January: $1500
February: $1200
March: $1800

Without the \n characters, all text would appear on a single line: Sales ReportJanuaryFebruaryMarch...

Return Value

The .write() method returns the count of characters written:

with open('example.txt', 'w') as f:
chars_written = f.write("Hello, World!")
print(f"Characters written: {chars_written}") # Output: 13

Understanding file.writelines(): Writing Multiple Strings

The .writelines() method is designed for writing an iterable (list, tuple, generator) of strings all at once. It's more efficient than looping with .write() when you have pre-built collections of strings.

Critical Detail: Also No Automatic Newlines

Just like .write(), .writelines() does not add newline characters between strings. Each string in your list must already contain \n if you want line breaks.

# writelines_example.py

guests = [
"Alice\n",
"Bob\n",
"Charlie\n",
"Diana\n"
]

with open('guests.txt', 'w') as f:
f.writelines(guests)

print("'guests.txt' has been generated.")

The resulting file contains four separate lines:

Alice
Bob
Charlie
Diana

What happens without newlines?

# Problematic code - no newlines in list
guests = ["Alice", "Bob", "Charlie"]

with open('guests.txt', 'w') as f:
f.writelines(guests)

# File contents: "AliceBobCharlie" (all on one line, illegible)

Choosing Between write() and writelines()

The choice depends on how your data is structured and whether you're building it incrementally or have it ready upfront.

Use .write() When:

  • Generating text on the fly, one piece at a time
  • Building complex strings with logic or formatting
  • Logging messages at unpredictable times
  • Writing formatted data line by line
# Typical logging pattern
with open('debug.log', 'w') as f:
for i in range(1, 4):
f.write(f"Processing item {i}...\n")
# Simulate work
f.write(f"Item {i} completed.\n")

Use .writelines() When:

  • You have a list of strings already prepared
  • Converting a pre-existing collection to a file
  • You want slightly better performance for large batches
# List comprehension creates all strings at once
data_points = [10, 25, 15, 30, 20]
lines_to_write = [f"Data point: {d}\n" for d in data_points]

with open('data_log.txt', 'w') as f:
f.writelines(lines_to_write)

File Modes: Overwrite vs. Append

The mode you choose when opening a file determines how .write() and .writelines() behave.

Mode 'w': Overwrite (Truncate)

with open('example.txt', 'w') as f:
f.write("This is new content.\n")
# Any existing content in example.txt is deleted

Mode 'a': Append

with open('example.txt', 'a') as f:
f.write("This line is added at the end.\n")
# Existing content is preserved

Practical Comparison

# First run: create and populate
with open('log.txt', 'w') as f:
f.write("Log started.\n")

# Later, add more entries without losing the first
with open('log.txt', 'a') as f:
f.write("New event occurred.\n")
f.write("Another event.\n")

# Result file:
# Log started.
# New event occurred.
# Another event.

Real-World Example: Processing and Writing Data

A common pattern combines reading, processing, and writing:

# Process and save report
data_points = [10, 25, 15, 30, 20]

# Convert numbers to formatted strings
lines_to_write = [
"Data Report\n",
"============\n"
]
lines_to_write.extend([f"Data point: {d}\n" for d in data_points])

# Calculate summary
lines_to_write.append(f"\nTotal: {sum(data_points)}\n")
lines_to_write.append(f"Average: {sum(data_points) / len(data_points):.2f}\n")

# Write all at once
with open('data_report.txt', 'w') as f:
f.writelines(lines_to_write)

print("Report written to data_report.txt")

Frequently Asked Questions

How do I ensure a newline at the end of each line?

Include \n explicitly in every string you write. This is the explicit contract: .write() and .writelines() do nothing automatic—you control the output completely.

with open('test.txt', 'w') as f:
f.write("Line 1\n")
f.write("Line 2\n")

What's the difference between 'w' and 'a' mode?

'w' (write) truncates the file—it deletes all existing content and starts fresh. 'a' (append) preserves existing content and adds new data to the end. Never confuse them or you may lose data.

Can I use writelines() with a generator?

Yes. .writelines() accepts any iterable, including generators. This is memory-efficient for large datasets:

def generate_lines(n):
for i in range(n):
yield f"Line {i}\n"

with open('huge.txt', 'w') as f:
f.writelines(generate_lines(1000000)) # Processes lazily

Should I always use 'with' statements for file writing?

Absolutely. The with statement automatically closes the file, even if an error occurs. This prevents data corruption and resource leaks. Never use open() without with.

How do I write bytes instead of strings?

Open the file in binary mode ('wb') and write bytes:

with open('binary.bin', 'wb') as f:
f.write(b"Binary data") # Note the `b` prefix

Further Reading