11 – Input and Output

Introduction to Python

Author

Clemens Brunner

Published

February 2, 2026

Introduction

We will now delve into simple input and output (I/O) operations, which includes activities such as getting input from the keyboard, reading text files, string formatting, and writing data to text files. Let’s start with string formatting.

String formatting

We are already familiar with the built-in print function. If we call print with an argument, the function will print this argument on the screen (more technically, it will write to standard output):

print("Hello")
Hello

The argument does not have to be a string, because print also works with numeric types:

print(55)
55

In fact, print accepts an arbitrary number of arguments:

print("Hello", "world", "this", "is", 2020)
Hello world this is 2020

When there is more than one argument, print automatically creates a space to separate the arguments in the output. We can use the sep argument to change the default from " " to any string we want. For example, we could set sep to an empty string:

print("Hello", "world", "this", "is", 2020, sep="")
Helloworldthisis2020

Strings are perfectly suited to output information either to the screen or to a file, because strings can represent almost any kind of information. Therefore, we can use the str function to convert arbitrary data types to strings:

str(55)
'55'

When writing a script, we often want to output information such as the result of a calculation. Suppose we compute the sum of two numbers a and b, and we would like to print the result in a nicely formatted way. Here’s one option using multiple arguments for the print function:

a = 5
b = 10
print(a, "+", b, "=", a + b)
5 + 10 = 15

Alternatively, we could build our desired output string and pass that as the only argument to print (remember that + concatenates strings):

print(str(a) + " + " + str(b) + " = " + str(a + b))
5 + 10 = 15

Notice that we must take care of whitespace ourselves, because the print function with one argument just outputs this argument.

f-strings

Constructing output strings like this quickly becomes cumbersome. Luckily, Python has a feature called f-strings, which greatly facilitates this task. An f-string (a “formatted” string) is a special way to define a string that may contain expressions (such as the names a and b from the previous example). Whenever Python encounters an expression enclosed in curly braces in an f-string, Python replaces that expression with its value. To define an f-string, we simply prepend f to the string literal (right before the opening quote):

f"This is an f-string"
'This is an f-string'

In this example, we don’t really need an f-string, because a regular string could also do the job.

Tip

Just to be clear, both a regular string and an f-string create a plain old str object. The difference is that during creation, f-strings support interpolating expressions into the resulting string object.

However, we can now add an expression inside the string, which Python will evaluate and replace in the result (note that we use the name a defined previously as a = 5):

f"The first number is {a}."
'The first number is 5.'

We could write the example output from before in a more straightforward way:

print(f"{a} + {b} = {a + b}")
5 + 10 = 15

Sometimes, it is necessary to control the format of the evaluated expressions. For example, suppose we want to print the digits of \(\pi\) with a precision of five decimal places. Let’s see what we get if we print the following f-string:

import math
print(f"The value of pi is approximately {math.pi}.")
The value of pi is approximately 3.141592653589793.

It seems like Python prints floating point numbers with 15 decimal places by default. We can change the format of expressions inside the curly braces with a special format specification mini-language. In a nutshell, we can optionally append a : and the desired format code after the expression. For example, we specify the precision of a floating point number to be five decimal places by appending :.5f:

print(f"The value of pi is approximately {math.pi:.5f}.")
The value of pi is approximately 3.14159.

Note that this doesn’t change the value of math.pi, but only affects how this number is formatted in the output.

The format specification mini-language is very powerful. It is worth going through some examples to find out what it can do, so make sure to consult the documentation whenever you need a specific output format.

Reading text files

Often, it is necessary to read data from a file. For example, a data analysis script in Python will need to import some data as one of the first steps. If the file is a text file (as opposed to a binary file), reading its contents is straightforward. The open function opens the specified file and returns a file handle object, which can be used to read from or write to the file:

f = open("text.txt")

By default, the function opens the file specified in the first argument in “read” mode. Other valid modes are “write” and “append”, which can be set with the mode parameter (the argument can take on the strings "r" for read, "w" for write, and "a" for append).

After opening the file, we can read, write, or append from/to the file (we’ll see how to do this in a minute). Once we’re done, we need to close the file by calling the close method:

f.close()

It is easy to forget to close the file, so Python provides a context manager (a with block), which automatically closes the file when leaving the block:

with open("text.txt") as f:
    print("read file contents using f")
    print("once we're done, we don't have to close the file")

print("Back to normal, the end of the with block closed the file automatically!")
read file contents using f
once we're done, we don't have to close the file
Back to normal, the end of the with block closed the file automatically!

We will now discuss which commands support reading the contents of a text file. To do this, we will use methods of the file object f. The read method reads the entire file and returns its contents as a single string. For example, let’s assume the file text.txt is located in the current working directory and contains the following five lines of text (there are three lines with text and two blank lines):

Hello!

This is just a test file containing some random text.

Nice!
Note

Remember that line breaks are actually just \n special characters, so the file contents is actually equal to this string:

Hello!\n\nThis is just a test file containing some random text.\n\nNice!

The following code snippet creates a string lines with the contents of the file:

with open("text.txt") as f:
    lines = f.read()

Indeed, lines is now associated with the following string:

lines
'Hello!\n\nThis is just a test file containing some random text.\n\nNice!'

The file handle f works like an old-fashioned tape drive. When you open a file, the file handle points at the start of the file. Every time you read from the file, the file handle moves forward past the already read characters. Therefore, if we read the whole contents at once using f.read(), the file handle points to the very end of the file.

If we then try to read from the file again, we get an empty string (assuming the file f is still open):

with open("text.txt") as f:
    lines = f.read()
    lines = f.read()
    print(lines)

The simplest way to read from the file a second time is to close it and open it again. That way, the file handle is initialized and points to the start of the file again.

Sometimes, it is useful to read the contents of a file line by line. For example, very large text files might be too large to fit into a single string object if the computer does not have enough memory. Instead, the readline method returns the contents of a file line by line:

with open("text.txt") as f:
    print("Line 1: ", f.readline(), end="")
    print("Line 2: ", f.readline(), end="")
    print("Line 3: ", f.readline(), end="")
Line 1:  Hello!
Line 2:  
Line 3:  This is just a test file containing some random text.

Since reading a file line by line is such a common task, we can also iterate over a file object, which will return one line in each iteration:

with open("text.txt") as f:
    for line in f:
        print(line, end="")
Hello!

This is just a test file containing some random text.

Nice!

This is the Pythonic way to read a text file. One of the perks of iterating is that we can modify the iteration in many useful ways. For example, iterating over enumerate(f) instead of just f returns a tuple of a counter (the current line number) and the contents of the current line:

with open("text.txt") as f:
    for no, line in enumerate(f):
        print(no, line, end="")
0 Hello!
1 
2 This is just a test file containing some random text.
3 
4 Nice!

Note that enumerate has a start parameter, which determines the initial value it returns (default 0). Therefore, if we want to start counting at 1, we can iterate over enumerate(f, start=1).

Writing text files

Writing text files is similar to reading. First, we open a file for writing by passing "w" as the mode argument. We then call the write method of the file handle and pass it a string, which will be the contents of the new file:

s = "This should go into the file."

with open("test2.txt", "w") as f:
    f.write(s)

Using mode="a", we can append to an existing file:

s = "\nMore content!"

with open("test2.txt", "a") as f:
    f.write(s)

Exercises

  1. Write all even numbers from 0 to 100 to a file called numbers.txt. The numbers should be separated by a comma. Hint: The ",".join method can be used to create a succinct solution.

  2. Use the random module to write 1000 random integers (from -1000 to 1000) to a file called random.txt. For reproducibility, initialize the random number generator with random.seed(7).

  3. Read the file random.txt created in the previous exercise. Convert the resulting string into a list of numbers. Finally, compute the mean and variance of all numbers using the mean and variance functions from the statistics module. Print these two statistics on the screen with a precision of two decimal places.

  4. Download the official Scrabble word list (twl06.txt) and put it into the current working directory. Using Python, count the number of valid Scrabble words. Note that the first two lines in the file should be ignored. Furthermore, the file contains one valid word per line. Since the file contains a large number of words, an efficient solution reads the file line by line (instead of the whole contents at once) to minimize memory use.

  5. Extend the solution to the previous example to find the longest valid Scrabble word. How many letters do the longest words have? Can you list all of them if there are more? Hint: Do not count the newline characters at the end of every line (you could use the strip method to remove any whitespace characters).


https://creativecommons.org/licenses/by-nc-sa/4.0/ This document is licensed under the CC BY-NC-SA 4.0 by Clemens Brunner.