Basic Input, Output, and String Formatting in Python

Basic Input, Output, and String Formatting in Python

by John Sturtz basics python

To be useful, a program usually needs to communicate with the outside world by obtaining input data from the user and displaying result data back to the user. This tutorial will introduce you to Python input and output.

Input may come directly from the user via the keyboard, or from some external source like a file or database. Output can be displayed directly to the console or IDE, to the screen via a Graphical User Interface (GUI), or again to an external source.

In the previous tutorial in this introductory series, you:

  • Saw a comparison of some different paradigms used by programming languages to implement definite iteration
  • Learned about iterables and iterators, two concepts that form the basis of definite iteration in Python
  • Tied it all together to learn about Python’s for loops

By the end of this tutorial, you’ll know how to:

  • Take user input from the keyboard with the built-in function input()
  • Display output to the console with the built-in function print()
  • Format string data with the string modulo operator

Without further ado, let’s dive in!

Reading Input From the Keyboard

Programs often need to obtain data from the user, usually by way of input from the keyboard. The simplest way to accomplish this in Python is with input().


Reads a line of input from the keyboard.

input() pauses program execution to allow the user to type in a line of input from the keyboard. Once the user presses the Enter key, all characters typed are read and returned as a string:

>>> s = input()
foo bar baz
>>> s
'foo bar baz'

Note that the newline generated when the user presses the Enter key isn’t included as part of the return string.

If you include the optional <prompt> argument, input() displays it as a prompt to the user before pausing to read input:

>>> name = input('What is your name? ')
What is your name? Winston Smith
>>> name
'Winston Smith'

input() always returns a string. If you want a numeric type, then you need to convert the string to the appropriate type with the int(), float(), or complex() built-in functions:

 1>>> n = input('Enter a number: ')
 2Enter a number: 50
 3>>> print(n + 100)
 4Traceback (most recent call last):
 5  File "<stdin>", line 1, in <module>
 6TypeError: must be str, not int
 8>>> n = int(input('Enter a number: '))
 9Enter a number: 50
10>>> print(n + 100)

In the example above, the expression n + 100 on line 3 is invalid because n is a string and 100 is an integer. Line 8 converts n to an integer so the print() statement on line 10 succeeds.

Writing Output to the Console

In addition to obtaining data from the user, a program will also usually need to present data back to the user. You can display program data to the console in Python with print().

Unformatted Console Output

To display objects to the console, pass them as a comma-separated list of arguments to print().

print(<obj>, ..., <obj>)

Displays a string representation of each <obj> to the console.

By default, print() separates each object by a single space and appends a newline to the end of the output:

>>> fname = 'Winston'
>>> lname = 'Smith'

>>> print('Name:', fname, lname)
Name: Winston Smith

Any type of object can be specified as an argument to print(). If an object isn’t a string, then print() converts it to an appropriate string representation displaying it:

>>> a = [1, 2, 3]
>>> type(a)
<class 'list'>

>>> b = -12
>>> type(b)
<class 'int'>

>>> d = {'foo': 1, 'bar': 2}
>>> type(d)
<class 'dict'>

>>> type(len)
<class 'builtin_function_or_method'>

>>> print(a, b, d, len)
[1, 2, 3] -12 {'foo': 1, 'bar': 2} <built-in function len>

As you can see, even complex types like lists, dictionaries, and functions can be displayed to the console with print().

Keyword Arguments to print()

print() takes a few additional arguments that provide modest control over the format of the output. Each of these is a special type of argument called a keyword argument. This introductory series of tutorials will include a tutorial on functions and parameter passing so you can learn more about keyword arguments.

For now, here’s what you need to know:

  • Keyword arguments have the form <keyword>=<value>.
  • Any keyword arguments passed to print() must come at the end, after the list of objects to display.

In the following sections, you’ll see how these keyword arguments affect console output produced by print().

The sep= Keyword Argument

Adding the keyword argument sep=<str> causes objects to be separated by the string <str> instead of the default single space:

>>> print('foo', 42, 'bar')
foo 42 bar

>>> print('foo', 42, 'bar', sep='/')

>>> print('foo', 42, 'bar', sep='...')

>>> d = {'foo': 1, 'bar': 2, 'baz': 3}
>>> for k, v in d.items():
...     print(k, v, sep=' -> ')
foo -> 1
bar -> 2
baz -> 3

To squish objects together without any space between them, specify sep='':

>>> print('foo', 42, 'bar', sep='')

You can specify any arbitrary string as the separator with the sep= keyword.

The end= Keyword Argument

The keyword argument end=<str> causes output to be terminated by <str> instead of the default newline:

>>> if True:
...     print('foo', end='/')
...     print(42, end='/')
...     print('bar')

For example, if you are displaying values in a loop, you might use end= to cause the values to be displayed on one line, rather than on individual lines:

>>> for n in range(10):
...     print(n)

>>> for n in range(10):
...     print(n, end=(' ' if n < 9 else '\n'))
0 1 2 3 4 5 6 7 8 9

Any string may be specified as the output terminator with the end= keyword.

Output Stream Keyword Arguments

print() accepts two additional keyword arguments, both of which affect handling of the output stream:

  1. file=<stream>: By default, print() sends its output to a default stream called sys.stdout, which is usually equivalent to the console. The file=<stream> argument causes output to be sent to an alternate stream designated by <stream> instead.

  2. flush=True: Ordinarily, print() buffers its output and only writes to the output stream intermittently. flush=True specifies that the output stream is forcibly flushed with each print().

These two keyword arguments are presented here for the sake of completeness. You probably don’t need to be too concerned about output streams at this point. They are discussed later in this series in the tutorial on File I/O.

Formatted String Output

print() supports formatting of console output that is rudimentary at best. You can choose how to separate printed objects, and you can specify what goes at the end of the printed line. That’s about it.

In many cases, you’ll need more precise control over the appearance of data destined for display. Python provides several ways to format output string data. In this section, you’ll learn about one of the older ones: the string modulo operator.

In recent versions of Python, there are newer ways to format string data that are arguably superior to the string modulo operator: the string .format() method, and f-strings. You will learn about these in the next tutorial in this series. You may also want to check out these articles:

Though other formatting options are available, the string modulo operator is still widely used. If you’re reading existing Python code, you are likely to encounter the string modulo operator, so it will be beneficial to familiarize yourself with it.

The String Modulo Operator

The modulo operator (%) is usually used with numbers, in which case it computes remainder from division:

>>> 11 % 3

With string operands, the modulo operator has an entirely different function: string formatting. (The two operations aren’t really much like one another. They share the same name because they are represented by the same symbol: %.)

Here’s what the syntax of the string modulo operator looks like:

<format_string> % <values>

On the left side of the % operator, <format_string> is a string containing one or more conversion specifiers. The <values> on the right side get inserted into <format_string> in place of the conversion specifiers. The resulting formatted string is the value of the expression.

Let’s get started with an example. Here’s a print() statement that displays a formatted string using the string modulo operator:

>>> print('%d %s cost $%.2f' % (6, 'bananas', 1.74))
6 bananas cost $1.74

In addition to representing the string modulo operation itself, the '%' character also denotes the conversion specifiers in the format string—in this case, '%d', '%s', and '%.2f'.

In the output, each item from the tuple of values is converted to a string value and inserted into the format string in place of the corresponding conversion specifier:

  • The first item in the tuple is 6, a numeric value that replaces '%d' in the format string.
  • The next item is the string value 'bananas', which replaces '%s'.
  • The last item is the float value 1.74, which replaces '%.2f'.

The resulting string is 6 bananas cost $1.74, as demonstrated in the following diagram:

Illustration of Python string modulo operator usage
The String Modulo Operator

If there are multiple values to insert, then they must be enclosed in a tuple as illustrated above. If there is only one value, then it can appear by itself:

>>> print('Hello, my name is %s.' % 'Graham')
Hello, my name is Graham.

Notice also that string modulo operation isn’t only for printing. You can also format values and assign them to another string variable:

>>> s = 'Hello, my name is %s.' % 'Graham'
>>> s
'Hello, my name is Graham.'

(Again, if you are familiar with the functions related to printf(), then this is reminiscent of sprintf(). If you aren’t, then don’t sweat it.)

Conversion Specifiers

Conversion specifiers appear in the <format_string> and determine how values are formatted when they’re inserted.

A conversion specifier begins with a % character and consists of these components:


% and <type> are required. The remaining components shown in square brackets are optional.

The following table summarizes what each component of a conversion specifier does:

Component Meaning
% Introduces the conversion specifier
<flags> Indicates one or more flags that exert finer control over formatting
<width> Specifies the minimum width of the formatted result
.<precision> Determines the length and precision of floating point or string output
<type> Indicates the type of conversion to be performed

Read on for more detail on how these work.

Conversion Type

The conversion type, <type>, is the last component of the conversion specifier:


It determines the type of conversion the corresponding value undergoes before insertion into the format string. Here’s a table that lists the possible conversion types:

<type> Conversion Type
d, i, u Decimal integer
x, X Hexadecimal integer
o Octal integer
f, F Floating point
e, E Exponential
g, G Floating point or Exponential
c Single character
s, r, a String
% Single '%' character

You’ll see how to use these conversion types in the following sections.

Integer Conversion Types

The d, i, u, x, X, and o conversion types correspond to integer values.

d, i, and u are functionally equivalent. They all convert the corresponding argument to a string representation of a decimal integer:

>>> '%d, %i, %u' % (42, 42, 42)
'42, 42, 42'

>>> '%d, %i, %u' % (-42, -42, -42)
'-42, -42, -42'

The value can either be positive or negative. If it is negative, then the resulting value will start with a '-' character.

x and X convert to a string representation of a hexadecimal integer value, and o converts to a string representation of an octal integer value:

>>> '%x, %X' % (252, 252)
'fc, FC'
>>> '%o' % 16

x produces lowercase output, and X produces uppercase. (Uppercase 'O' is not a valid conversion type.)

You can gain some additional control over the resulting format by using conversion flags, which you’ll learn more about in an upcoming section.

Floating Point Conversion Types

Conversion types f and F convert to a string representation of a floating point number, while e and E produce a string representing exponential (scientific) notation:

>>> '%f, %F' % (3.14159, 3.14)
'3.141590, 3.140000'
>>> '%e, %E' % (1000.0, 1000.0)
'1.000000e+03, 1.000000E+03'

e produces lowercase output, and E produces uppercase.

Deep Dive: inf and NaN

Under some circumstances, a floating-point operation can result in a value that is essentially infinite. The string representation of such a number in Python is 'inf'.

It also may happen that a floating-point operation produces a value that is not representable as a number. Python represents this with the string 'NaN'.

When these values are converted with the string modulo operator, the conversion type character controls the case of the resulting output. f and e produce lowercase output, while F and E produce uppercase:

>>> x = float('NaN')
>>> '%f, %e, %F, %E' % (x, x, x, x)
'nan, nan, NAN, NAN'
>>> y = float('Inf')
>>> '%f, %e, %F, %E' % (y, y, y, y)
'inf, inf, INF, INF'

This is the only difference between the f and F conversion types.

The g and G conversion types choose between floating point or exponential output, depending on the magnitude of the exponent and the value specified for .<precision>. (See below.) Output is the same as e/E if the exponent is less than -4 or not less than .<precision>. Otherwise, it’s the same as f/F:

>>> '%g' % 3.14

>>> '%g' % 0.00000003
>>> '%G' % 0.00000003

Basically, you can think of these conversion types as making a “reasonable” choice. They’ll produce floating point output if the value in question is reasonably suitable for it, and exponential format otherwise.

Similar to the other floating point conversion types, g produces lowercase output, and G produces uppercase.

Character Conversion Types

c inserts a single character. The corresponding value may be either an integer or a single-character string:

>>> '%c' % 97

>>> '[%c]' % 'y'

The c conversion type supports conversion to Unicode characters as well:

>>> '%c' % 8721

s, r, and a produce string output using the built-in functions str(), repr(), and ascii(), respectively:

>>> '%s' % 'foo'
>>> '%r' % 'foo'
>>> '%a' % 'foo'

The justification and padding of string output can be controlled with the <width> and .<precision> specifiers, as you will see shortly.

Inserting a '%' Character

To insert a literal '%' character into the output, specify two consecutive % characters in the format string. The first introduces a conversion specifier (as usual), and the second specifies that the conversion type is %, which results in a single '%' character in the output.

In this example, %d%% means a decimal integer conversion type followed by a literal '%' character:

>>> 'Get %d%% off on %s today only!' % (30, 'bananas')
'Get 30% off on bananas today only!'

Note that the % conversion type doesn’t consume any of the <values> to the right of the string modulo operator.

Width and Precision Specifiers

<width> and .<precision> sit in the middle of the conversion specifier:


They determine how much horizontal space a formatted value occupies.

The <width> Specifier

<width> specifies the minimum width of the output field. If the output is shorter than <width>, then by default it is right-justified in a field that is <width> characters wide, and padded with ASCII space characters on the left:

>>> '%5s' % 'foo'
'  foo'

>>> '%3d' % 4
'  4'

(The justification and padding character can be modified. See conversion flags below.)

If the output length is greater than <width>, then <width> has no effect:

>>> '%2d' % 1234, '%d' % 1234
('1234', '1234')
>>> '%2s' % 'foobar', '%s' % 'foobar'
('foobar', 'foobar')

Each of these examples specifies a field width of 2. But since the values to be formatted are more than two characters, the result is the same as when no <width> is specified.

The .<precision> Specifier

.<precision> affects the floating point, exponential, and string conversion types.

For the f, F, e, and E types, .<precision> determines the number of digits after the decimal point:

>>> '%.2f' % 123.456789

>>> '%.2e' % 123.456789

For the g and G types, .<precision> determines the total number of significant digits before and after the decimal point:

>>> '%.2g' % 123.456789

String values formatted with the s, r, and a types are truncated to the length specified by .<precision>:

>>> '%.4s' % 'foobar'

It is very common to see <width> and .<precision> used together:

>>> '%8.2f' % 123.45678
'  123.46'

>>> '%8.3s' % 'foobar'
'     foo'

Either of <width> or .<precision> can be specified as an asterisk character (*), in which case the value to be used is taken from the next item in the <values> tuple:

>>> '%*d' % (5, 123)
'  123'

There isn’t much need for this when the <width> value is given as a constant. There isn’t any functional difference between the example given above and this:

>>> '%5d' % 123
'  123'

But you can also specify <width> and .<precision> by variable:

>>> for i in range(3):
...     w = int(input('Enter width: '))
...     print('[%*s]' % (w, 'foo'))
Enter width: 2
Enter width: 4
[ foo]
Enter width: 8
[     foo]

This allows the width or precision to be determined at run-time, and potentially change from one execution to the next.

Conversion Flags

Optional conversion <flags> are specified just after the initial % character:


These allow finer control over the display of certain conversion types. <flags> can include any of the characters shown in the following table:

Character Controls
# Display of base or decimal point for integer and floating point values
0 Padding of values that are shorter than the specified field width
- Justification of values that are shorter than the specified field width
' ' (space)
Display of leading sign for numeric values

The following sections explain how conversion flags operate in greater detail.

The # Flag

For the octal and hexadecimal conversion types, the # flag causes base information to be included in the formatted output. For the o conversion type, this flag adds a leading '0o'. For the x and X conversion types, it adds a leading '0x' or '0X':

>>> '%#o' % 16

>>> '%#x' % 16, '%#X' % 16
('0x10', '0X10')

The # flag is ignored for the decimal conversion types d, i, and u.

For floating point values, the # flag forces the output to always contain a decimal point. Ordinarily, floating point values will not contain a decimal point if there aren’t any digits after it. This flag forces a decimal point to be included:

>>> '%.0f' % 123
>>> '%#.0f' % 123

>>> '%.0e' % 123
>>> '%#.0e' % 123

This also works for values displayed in exponential notation, as shown.

The 0 Flag

When a formatted numeric value is shorter than the specified field width, the default behavior is to pad the field with ASCII space characters. The 0 flag causes padding with '0' characters instead:

>>> '%05d' % 123

>>> '%08.2f' % 1.2

The 0 flag can be used with all the numeric conversion types: d, i, u, x, X, o, f, F, e, E, g, and G.

The - Flag

When a formatted value is shorter than the specified field width, it is usually right-justified in the field. The - flag causes the value to be left-justified in the specified field instead:

>>> '%-5d' % 123
'123  '

>>> '%-8.2f' % 123.3
'123.30  '

>>> '%-*s' % (10, 'foo')
'foo       '

You can use the - flag with the string conversion types s, a, and r, as well as all the numeric conversion types. For numeric types, if both 0 and - are present, then 0 is ignored.

The + and ' ' Flags

By default, positive numeric values do not have a leading sign character. The + flag adds a '+' character to the left of numeric output:

>>> '%+d' % 3
>>> '%+5d' % 3
'   +3'

The ' ' (space character) flag causes positive numeric values to be preceded by a space character:

>>> '% d' % 3
' 3'

These flags have no effect on negative numeric values, which always have a leading '-' character.

Specifying Values by Dictionary Mapping

The <values> inserted into the format string may be specified as a dictionary instead of a tuple. In that case, each conversion specifier must contain one of the dictionary keys in parentheses immediately following the '%' character.

Here’s an example:

>>> '%d %s cost $%.2f' % (6, 'bananas', 1.74)
'6 bananas cost $1.74'

>>> d = {'quantity': 6, 'item': 'bananas', 'price': 1.74}
>>> '%(quantity)d %(item)s cost $%(price).2f' % d
'6 bananas cost $1.74'

Using this technique, you can specify the inserted values in any order:

>>> d = {'quantity': 6, 'item': 'bananas', 'price': 1.74}

>>> '%(quantity)d %(item)s cost $%(price).2f' % d
'6 bananas cost $1.74'

>>> 'It will cost you $%(price).2f for %(item)s, if you buy %(quantity)d' % d
'It will cost you $1.74 for bananas, if you buy 6'

All the conversion specifier items shown above—<flags>, <width>, .<precision>, and <type>—still have the same meaning:

>>> 'Quantity: %(quantity)03d' % d
'Quantity: 006'

>>> 'Item:     %(item).5s' % d
'Item:     banan'

Python Input and Output: Conclusion

In this tutorial, you learned about Python input and output, and how your Python program can communicate with the user. You should now be able to obtain data from the user with input(), and display results to the console with print().

You also learned how to make data displayed to the user more presentable by formatting it with the string modulo operator.

As versatile as the string modulo operator is, Python provides two newer ways to format string data that are even better: the string .format() method and the formatted string literal. Head to the next tutorial to learn about them!

🐍 Python Tricks 💌

Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Python Tricks Dictionary Merge

About John Sturtz

John Sturtz John Sturtz

John is an avid Pythonista and a member of the Real Python tutorial team.

» More about John

Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

Master Real-World Python Skills With Unlimited Access to Real Python

Join us and get access to hundreds of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

Master Real-World Python Skills
With Unlimited Access to Real Python

Join us and get access to hundreds of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

What Do You Think?

Real Python Comment Policy: The most useful comments are those written with the goal of learning from or helping out other readers—after reading the whole article and all the earlier comments. Complaints and insults generally won’t make the cut here.

What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.

Keep Learning

Related Tutorial Categories: basics python