Python is the most popular programming language which is widely used for a variety of applications, from Web Development to Scientific Computing, Artificial Intelligence, Machine Learning to Quantum Computing, and Data Science. What makes it so attractive for students, data scientists and programmers is its simplicity, readability, and flexibility, and of course, its large and active community contributes to its growth and development.
print("Hello World!")
One of the most commonly used functions of Python is the print() function, which allows developers to output text to the console. The print() function may seem simple at first glance, but there are many advanced techniques and features that can help developers get the most out of it.
In this tutorial, we will explore advanced techniques and features of the print() function in Python in depth. We will cover different ways to format output, advanced usage of the function, tips for debugging with print(), common mistakes to avoid, and alternative print functions available in Python
The print() function is used to output text to the console.
It is a built-in function, which means that it is available by default and does not require any special setup or a need to import of any special module. You can use the print() function to output simple text messages, variable values, and complex data structures to the console, making it an essential tool for debugging and development.
Unserstanding the Syntax of print() function
The print() function in Python has several parameters that allow developers to customize the output.
Signature of the print() function as of Python version 3.11 :
A variable-length argument that represents the objects to be printed, here * indicates that there can be one or more objects. Multiple objects separated by commas can be passed in. This is also known as the unpacking operator.
*objects parameter was introduced in Python version 2.0. Before that, a fixed number of objects had to be passed to the print() function by putting them into a tuple or list.
sep=''
:
Specifies the separator between the objects that are printed. The default is a space character (' '), but a custom separator value can be specified.
sep parameter was introduced in Python version 3.0. Before that, the default behavior was to end the output with a newline character.
end='\n'
:
Specifies the output stream. By default, it is set to None, which means that the output will be printed on the console. The value of the file object can be changed to redirect the output to a file.
Like sep end parameter was also introduced in Python version 3.0, and before that, the default separator was a space character.
file=None
:
Specifies the output stream. By default, it is set to None, which means that the output will be printed on the console. The value of the file object can be changed to redirect the output to a file.
file parameter was introduced in Python version 2.0. Before that, the only way to redirect the output of print() was to make use of the sys.stdout object.
flush
:
Specifies whether the output stream should be flushed or not. By default, it is set to False, so the stream is not flushed. If set to True, the output will be flushed immediately after it is written to the stream.
flush parameter was introduced in Python recently in the 3.3 version. Earlier to this version, the output buffer was automatically flushed whenever a newline character was encountered.
The official documentation defines the print function as follows.
"Print objects to the text stream file, separated by sep and followed by end. sep, end, file, and flush, if present, must be given as keyword arguments."
Deep Dive into print function Parameters with Examples
The previous section provided an overview of each parameter of the print function and its purpose, but it can still be a bit unclear how they all work together without some practical examples. Therefore, let's take a deep dive by exploring some code examples that use a permutation and combination of these parameters to get a better understanding of how they work together..
1. Parameter *object
Usage: To represent the objects to be printed.
Explanation: It is a variable-length argument that allows one or more objects to be passed to the print() function, separated by commas. It is also known as the unpacking operator.
Note: print(*fruits) and print(fruits) are not the same.
print(*fruits) will print each element of the iterable fruits as separate arguments, with a space separator between them. Here as we have not passed any custom sep value it is ' ' (space).
print(fruits) will print the entire iterable fruits as a single object, without any separator between the elements.
print(*fruits)
pawpaw persimmon chokeberry
print(fruits)
['pawpaw', 'persimmon', 'chokeberry']
2. Seperator parameter: sep=''
Usage: Specifies the separator between objects.
Explanation: Allows you to change the default behavior of the separator, which is a space character (' ').
Examples of usage of sep parameter
We will build on the same examples so its easier to co-relate.
Explanation: By default, set to None, which prints the output on the console. We will change the value of the file object to redirect the output to a file.
Usage: Specifies whether the output stream should be flushed or not.
Explanation: By default, it is set to False, which means the stream is not flushed. we will see examples where we set it to True, so that the output will be flushed immediately after it is written to the stream.
Example:
import time
for i in range(5):
print(f"Task {i+1}", end=' - ')
time.sleep(1)
print('completed!', flush=True)
As we have set the flush parameter as True, each output is immediately written to the console as soon as it is generated. Its important to note here is without flush=True, the output would be buffered until the buffer is full or a newline character is encountered.
Examples with a combination of all parameters of print function
I am sure that now we understand all the parameters of the print function in Python. It is time to take a look at them working together as real-life use cases.
1. Using objects and variables and creating a sentence.
name = "Andrew"
age = 19
city = "New York"
print("My name is", name, "and I am", age, "years old, and I live in ",city, end=".", sep=" ", file=open("message.txt", "w"))
My name is Andrew and I am 19 years old, and I live in New York.
Name Age Location
-----------------------------------
Sam 32 Chicago
-----------------------------------
Dean 36 Texas
-----------------------------------
Bobby 63 New York
-----------------------------------
Castiel 42 California
-----------------------------------
Crowley 55 North Carolina
-----------------------------------
If looking at the output table you are wondering it does not look to be printing the table format with proper indentation! Well you are writing, this is what we will be covering in the next section.
Name Age Location
---------------------------------------------------
Sam 32 Chicago
---------------------------------------------------
Dean 36 Texas
---------------------------------------------------
Bobby 63 New York
---------------------------------------------------
Castiel 42 California
---------------------------------------------------
Crowley 55 North Carolina
---------------------------------------------------
Introduction: f-strings
PEP 498 a feature introduced in Python 3.6 is a new way of formatting strings known as "Literal String Interpolation", or more commonly referred to as f-strings. Using f-strings, you can embed expressions directly inside string literals by prefixing them with the letter 'f'. This makes for a very concise and readable way of formatting strings that can greatly improve the readability and maintainability of your code.
Syntax:
f"Some String Literal {expression-1} more text {expression-2} ..."
The f-strings literal string expressions are evaluated at run-time, and they are expressed with curly braces as shown above.
Example:
name = "Andrew"
age = 19
city ="New York"
message = f"My name is {name} and I am {age} years old. I live in {city}."
print(message)
My name is Andrew and I am 19 years old. I live in New York.
f-strings are a powerful tool to make it easy for you to create complex strings with embedded expressions. Another reason to make use of f-strings is they are highly readable thus making it easy to understand the meaning of the string without having to mentally parse complex formatting codes.
The old way of %-strings and why not to use it.
message = "My name is %s and I am %d years old. I live in %s." % (name, age, city)
print(message)
As you can see, the %-string format is an old-school way of formatting print messages and it requires a lot of placeholders, the values have to be passed in a separate tuple. It can be hard to understand and maintain for complex strings with multiple placeholders so should be avoided.
String interpolation using f-strings
String interpolation in Python is a way to embed expressions inside string literals, it allows you to construct strings that include variable values, expressions, and function calls.
name = "Andrew"
age = 19
city = "New York"
num_to_word = { 19:"nineteen" }
message = f"My name is {name} and I am {num_to_word[age]} years old. I live in {city}."
print(message)
My name is Andrew and I am nineteen years old. I live in New York.
In the above example, we are using f-strings interpolation to create a message string that includes variable values and a dictionary lookup.
Formatting of variables and expressions within f-strings
String formatting is a very essential part of any programming language, and Python offers the most advanced ways to format strings.
In the below table, we explore the syntax and usage of various formatting options available within f-strings.
Syntax
Description
Example
Output
{}
Positional Argument
f"My name is {}, I am {} years old".format(name, age)
My name is Andrew, I am 19 years old
{index}
Positional Argument with Index
f"My name is {0}, I am {1} years old".format(name, age)
My name is Andrew, I am 19 years old
{var}
Variable Name
f"My name is {name}, I am {age} years old"
My name is Andrew, I am 19 years old
{expr}
Expression
f"Next year, I will be {age+1} years old"
Next year, I will be 20 years old
{var.method()}
Method
f"My name is {name.upper()}, I am {age} years old"
My name is ANDREW, I am 19 years old
{var.attribute}
Attribute
f"I am from {city.title()}"
I am from New York
{var[index]}
Indexed Value
f"My name starts with {name[0]}"
My name starts with A
{var[start:stop]}
Slice
f"I live in {city[:3]}"
I live in New
{var:{width}}
Minimum Width
f"My name is {name:{10}}"
My name is Andrew
{var:{width}.{precision}}
Width and Precision
f"I am {age:{5}.{2}} years old"
I am 19.00 years old
{var:!^width}
Fill and Align
f"I am {name:!^10}."
I am !!Andrew!!
{var:=^width}
Fill and Align
f"I am {name:=$^10}."
I am ==Andrew==
{var:!<width}}
Fill and Align
f"I am {name:!>10}."
I am !!!!!Andrew
Let's take our old table example and see how we can format the output as a table in the console using f-strings and various formatting styles.
print("Name\t\tAge\tLocation")
print(end_str)
for i in range(len(names)):
print(f"{names[i]:<10}{ages[i]:<10}{locations[i]:<15}")
print(end_str)
Name Age Location
-----------------------------------
Sam 32 Chicago
Dean 36 Texas
Bobby 63 New York
Castiel 42 California
Crowley 55 North Carolina
-----------------------------------
Table data right aligned
name="Name"
age="Age"
location="Location"
print(f"{name:>10}{age:>10}{location:>20}")
print(end_str)
for i in range(len(names)):
print(f"{names[i]:>10}{ages[i]:>10}{locations[i]:>20}")
print(end_str)
Name Age Location
-------------------------------------------
Sam 32 Chicago
Dean 36 Texas
Bobby 63 New York
Castiel 42 California
Crowley 55 North Carolina
-------------------------------------------
Table data center aligned
print(f"{name:^10}{age:^10}{location:^20}")
print(end_str)
for i in range(len(names)):
print(f"{names[i]:^10}{ages[i]:^10}{locations[i]:^20}")
print(end_str)
Name Age Location
-------------------------------------------
Sam 32 Chicago
Dean 36 Texas
Bobby 63 New York
Castiel 42 California
Crowley 55 North Carolina
-------------------------------------------
As you would have understood, the formatting codes used in the f-strings above are,
< for left alignment.
^ for center alignment.
> for right alignment.
You can adjust these values as needed to customize the table formatting to your liking.
Fill and Align Example:
for i in range(len(names)):
print(f"{names[i]:_>10}{ages[i]:,>10}{locations[i]:/>20}")
Name Age Location
-------------------------------------------
_______Sam,,,,,,,,32/////////////Chicago
______Dean,,,,,,,,36///////////////Texas
_____Bobby,,,,,,,,63////////////New York
___Castiel,,,,,,,,42//////////California
___Crowley,,,,,,,,55//////North Carolina
-------------------------------------------
f-strings with dictionaries example
person = {'name': 'Andrew', 'age': 19}
message = f"My name is {person['name']} and I am {person['age']} years old."
print(message)
My name is Andrew and I am 19 years old.
Nested f-strings example
name = "Andrew"
age = 19
city = "New York"
message = f"My name is {name} and I am {age} years old. I live in {city}."
nested_message = f"Here's my info: {message}"
print(nested_message)
Here's my info: My name is Andrew and I am 19 years old. I live in New York.
Common errors/exceptions and how to debug f-strings
NameError
name = "Andrew"
age = 19
message = f"My name is {naem} and I am {age} years old."
NameError: name 'naem' is not defined
If you provide an incorrect name for a variable, you will get a NameError.
Debugging f-String
name = "Andrew"
age = 19
message = f"My name is {name=} and I am {age} years old."
print(message)
My name is name='Andrew' and I am 19 years old.
When you are unsure what the value of a variable is when used within an f-string, you can simply add a = sign next to the variable, this is called debugging the f-string where-in you will see that name of the variable and its value is printed out enclosed within single quotes.
Error handling using f-string
try:
x = 1 / 0
except ZeroDivisionError as e:
message = f"An error occurred: {e}"
You can use f-strings to catch and handle exceptions by wrapping the expression in a try-except block.
If the code inside the try block raises a ZeroDivisionError, the exception will be caught and the error message will be included in the f-strings.
Using !r as a Conversion Flag in f-strings to Debug unexpected behaviors
!r is the conversion flag in Python that is used to represent the value as a string using the repr() method, which returns a printable representation of an object.
name = "Andrew"
age = 19
print(f"My name is {name!r} and I am {age} years old.")
My name is 'Andrew' and I am 19 years old.
The !r conversion flag can be very useful for debugging f-strings as it shows the printable representation of an object.
This can really help to identify any unexpected behavior in your code.
name = "Andrew\n"
age = 19
print(f"My name is {name} and I am {age} years old.")
print(f"My name is {name!r} and I am {age} years old.")
Example to know if the value contains special characters or escape sequences, using !r can help you see exactly what those characters are.
My name is Andrew
and I am 19 years old.
My name is 'Andrew\n' and I am 19 years old.
As you can see by adding !r to the name variable in the second print function, we were able to identify why there was a line break.
Common Errors/Exception with print function
Syntax Error:
print "Hello World!"
SyntaxError: Missing parentheses in call to 'print'. Did you mean print("Hello, world!")?
If you forget to add parentheses around the argument, you will get a syntax error. The error stack is quite detailed to let you know that you need to enclose the print calls with parentheses.
Fix:
print("Hello World!")
Type Error:
name ="Andrew"
age = 19
print(f"{name} is "+ age + " years old.")
TypeError: can only concatenate str (not "int") to str
TypeError occurs when the argument passed to the print() function is not of the correct data type.
Fix:
print(f"{name} is "+ str(age) +" years old.")
As you can see we cast the int value to a string for the concatenation to work.
Name Error:
name ="Andrew"
age = 19
print(f"{name} is {aeg} years old. I live in {my_city}")
NameError: name 'aeg' is not defined NameError: name 'my_city' is not defined
NameError occurs when a variable is misspelled or undefined and used as an argument in the print() function.
Fix:
name ="Andrew"
age = 19
my_city = "New York"
print(f"{name} is {age} years old. I live in {my_city}")
As you can see we cast the int value to a string for the concatenation to work.
Indentation Error:
name ="Andrew"
age = 19
if age > 18:
print(f"{name} are an adult.")
IndentationError: expected an indented block
This is Python 101 error! If you do not indent your code right, you will get IndentationError.
Unicode Encode Error:
print("Andrew likes french café! ☕️")
>>> print("Andrew likes french café! ☕️".encode('ascii'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\u0301' in
position 18: ordinal not in range(128)
Fix:
name ="Andrew"
age = 19
if age > 18:
print(f"{name} are an adult.")
If your string or value of variables used within a print function has UTF-8 characters, you need to encode the print function.
Fix:
print("Andrew likes french café! ☕️").encode('utf-8'))
You would not get this error if you are using Python 3+ as all strings in Python 3 and above work with UTF-8 characters.
In Python 2, a u prefix was used to denote Unicode strings.
print(u"Andrew likes french café! ☕️")
More advanced usage of print function with Python modules
Custom print function using functools module
If you have a special need to change the custom behavior of the built-in print function in Python, you can make use of the functools module to achieve this.
As you can see we have set custom values for sep, end, and file parameters. This could be something one may use for custom logging using print function.
Coloring the print fuction output
from termcolor import colored
print(colored('Hello, world!','white','on_blue'))
You can make use of the module termcolor (will need to pip install) to color code the print output in the console, you can do a lot of stuff here like.
Some of the features provided by the termcolor module:
Colored text output in the terminal using ANSI escape sequences
Support for different text attributes, such as bold, underline, and blink
Support for different foreground and background colors
Easy to use API for coloring text and printing it to the terminal
Support for nested colored text using the colored() function
The tqdm module is a third-party library that provides an easy way to add progress bars to Python code. It is commonly used in loops or when iterating over large datasets to keep track of how much time is left until the task is completed.
Some of the features provided by the tqdm module:
Progress bars for loops and iterable objects
Customizable progress bar styles and appearance options
Dynamic progress meter
Display of elapsed time, estimated time remaining, and progress percentage
Optional smoothing of progress updates
Support for nested progress bars
Integration with other third-party libraries and tools
Example: Progress status using print function
from tqdm import tqdm
import time
for i in tqdm(range(10)):
print(f"Building AI Model {i}")
time.sleep(1)
print("AI Model is ready to use!")
0%| | 0/4 [00:00<?, ?it/s] Building AI Model 0
25%|██▌ | 1/4 [00:01<00:03, 1.00s/it] Building AI Model 1
50%|█████ | 2/4 [00:02<00:02, 1.00s/it] Building AI Model 2
75%|███████▌ | 3/4 [00:03<00:01, 1.00s/it] Building AI Model 3
100%|██████████| 4/4 [00:04<00:00, 1.00s/it] AI Model is ready to use!
The print function is used to display output in the console.
It takes one or more objects as input, which are separated by a comma by default.
The separator can be changed using the sep parameter.
The end character can be changed using the end parameter.
The output can be redirected to a file using the file parameter.
The flush parameter can be used to force the output to be immediately written to the console or file.
f-strings are a new way to format strings in Python that allow you to embed expressions and variables inside curly braces {}.
Nested f-strings can be used to format multiple variables or expressions in a single string.
Conversion flags can be used inside f-strings to change how variables are displayed, such as using the !r flag to display a printable representation of an object.
The logging module can be used for more advanced logging instead of using print statements.
functools.partial can be used to create a customized print function with preset arguments.
The termcolor module can be used to colorize text in the console.
The progress bar can be created using the tqdm module to show the progress of long-running tasks.
Errors can occur with the print function due to syntax, type, name, and Unicode encoding issues.
Debugging techniques, such as using the repr function or printing variables, can be used to fix errors in the print function.
Comments & Discussion
Facing issues? Have questions? Post them here! We're happy to help!