Python has a huge collection of builtin modules which come bundled together with the interpreter. To use the built-in modules, we do not need to perform any extra installations, we just have to import them in our programs.

There are well over two hundred builtin standard libraries, you may already be familiar with some of them while others you will rarely or even never use.  In this article we will look at the top 12 libraries which we think every Python developer should be familiar with. The order they are listed may not be very important as each of the libraries has its own purpose and usage domain.

We will not cover every small detail about each library but links will be included whenever possible so that you can explore further on each module. 

collections

The collections module provide a number of handy data structures that can be used as alternatives to the basic container types like lists, dictionaries, tuples e.t.c.

Among the structures defined in the collections module are:

The above structures are very convenient in their respective use cases. For example, the namedtuple is an extension of the regular tuples which allows the elements in a tuple to be accessed through an index(as in regular tuple) as well as through an attribute name that is specified during instantiation.

from collections import namedtuple

Point = namedtuple("Point", ['x', 'y'])

p = Point(3, 5)

print(p.x, p.y) #using attributes
print(p[0], p[1]) # using indexes

Counter is another structure defined in the collections module, it keeps the count of occurrences of distinct elements in a collection.

from collections import Counter

data = "aaabcccbcdddccccd"

c = Counter(data)
print(c)

print(c['d']) #get the count of an individual element

You can look follow the links previously listed to see more on the structures.

math

The math module is deservedly one of the most popular standard library modules. It provides useful functions for performing math operations. The module works only with real numbers but there is a similar module called cmath( complex math ) for complex numbers.

This module provides mathematical functions which are implemented directly in the C language.

import math

print(math.pow(5, 3)) # power

print(math.sqrt(64)) #square root

print(math.sin(math.radians(30))) # sine of an angle in radians

print(math.pi) #pi
print(math.e) #euler's number

datetime

Working with dates and time is very vital when making software systems of any size.

The datetime library provides tools that eases usage, manipulation and formatting of dates and time.

At the heart of the datetime module is a class with an identical name(datetime), the class provides a way to represent values for both dates and time.

from datetime import datetime #import the datetime class

dt = datetime.now()

print(dt)

print(dt.year)
print(dt.month)
print(dt.day)

print(dt.ctime())

Apart from the datetime class,  other important classes in the datetime module includes:

random

The random module provides powerful tools for generating pseudo-random numbers. These makes it possible for a program to perform randomized operations. For example, the random.sample() function generates a sample given a dataset.

import random

data = range(100)

print(random.sample(data, 10))

The random.shuffle() function rearranges the elements of a list in a random order.

import random

data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

random.shuffle(data)

print(data)

You can view more functions in the random library here.

itertools

Using iterators is a very handy technique which is generally more efficient and faster than alternative approaches. Iterators uses lazy evaluation allowing an element to be accessed only when it is needed.

The itertools module provides tools for working with and creating iterators. Functions defined in this module includes:

  • chain()
  • accumulate()
  • product()
  • permutations()
  • combinations()
  • e.tc

For example, the chain() function creates an iterator that traverses through the elements of multiple iterables as if it was a single iterable. Note that this is much more efficient than concatenating the iterables first.

import itertools

L1 = [1, 2, 3, 5]
L2 = [100, 150, 200, 250]
L3 = [1000, 2000, 3000]

for n in itertools.chain(L1, L2, L3):
   print(n)

As you can see above the three lists are traversed as if it was just a single list.

There are more functions defined in the itertools module, you can view them here.

functools

The functools module provides tools for functional programming. The functions and classes in the module can be used to manipulate functions in various ways.

One of the most important class defined in the functools module is partial, which is used to create partial functions. A partial function is a specialized versions of a given function in which some arguments are pre-filled in advance. Consider the following example.

import functools

def power(a, b):
   return a ** b

square = functools.partial(power, b = 2)
cube = functools.partial(power, b = 3)

print(square(5))
print(cube(5))

In the above example, we defined the power() function then created two partial functions i.e square() and cube() from it. The two partial function have argument b pre-filled with the relevant values.

There are other functions defined in the functools module, you can see how they work here

sys

The sys module provide functions and variables for interacting with the interpreter during runtime. We can use this module to manipulate the runtime environment in various ways.

For example, the sys.path is a list which contains pathnames to the directories where Python will look for modules during import operations. We can modify this list by adding or removing pathnames  to update locations where Python should look for modules.

import sys

print(sys.path)

os

The os module provides utilities for interacting with the underlying operating system. We can use the module to get information about the operating system as well as manipulate the OS to some degree. 

import os

print(os.name) #the name of the operating system
print(os.getuid())

re

The re module is the basic tool for working with regular expression in python. Regular expressions are a powerful and expressive way for matching patterns and manipulating texts data.

The re module provide a number of functions and other tools for creating regular expressions and generally manipulating text information.

The following is a basic example that uses some functions and methods defined in re.

#import the module
import re

#the pattern
pattern = "valuable"

#text to be scanned
text = "Eric has proved himself to be a valuable asset to the team."

match = re.search(pattern, text)

s = match.start() #The starting index
e = match.end() #The ending index

print("""Found "%s"
in: %s
from index %d to index %d("%s")."""%(match.re.pattern, match.string, s, e, text[s:e]))

asyncio

Asynchronous programming is a very effective way of achieving concurrency within a single thread. 

The asyncio library provides a set of tools to execute and generally manage asynchronous tasks. 

asyncio.run() is one of the most popular and commonly used functions from the asyncio library. It provides a higher-level way to execute an asynchronous coroutine.

import asyncio

#a coroutine
async def task1():
   for n in range(5):
      print(n)
      await asyncio.sleep(0.001) #cause a small delay

async def task2():
   for letter in "ABCDE":
      print(letter)
      await asyncio.sleep(0.001) #cause a small delay

async def main():
   print('Started')
   await asyncio.gather(task1(), task2())
   print("Finished")

asyncio.run(main())  #call asyncio.run()

In the above example, we implemented a simple asynchronous program using functions from the asyncio library in various parts. As you can see from the output, the two coroutines i.e task1() and task2() are executed concurrently.

See how to use asyncio in Python.

threading

The threading library provides the necessary tools for creating and managing threads in a multi-threaded program .

In the previous sub-heading, we saw that the asyncio library can be used to achieve concurrency within a single thread. Similarly multi-threading makes it possible to achieve concurrency using multiple thread within the same process. It is more light-weight compared to multi-processing.

In the following example we will implement a simple multi-threaded program.

import threading, time

#a coroutine
def task1():
   for n in range(5):
      print(n)
      time.sleep(0.001) #cause a small delay

def task2():
   for letter in "ABCDE":
      print(letter)
      time.sleep(0.001) #cause a small delay

if __name__ == "__main__":
   print('Started')

   #create two threads for the tasks
   T1 = threading.Thread(target = task1)
   T2 = threading.Thread(target = task2) 

   T1.start()
   T2.start()

   T1.join()
   T2.join()

   print('Finished')

 See Multithreading in Python.

multiprocessing

The multiprocessing module provides tools for creating and managing processes.

Multi-processing occurs when a program runs multiple processes simultaneously. This is also another way of achieving concurrency just like with asynchronous programming and multi-threading.

Creating and running multiple processes is much like in threads, the multiprocessing module has an interface that is very similar to that of threading(from previous sub-heading). In the following example, we create a simple program which utilizes the multiple processes to achieve concurrency.

import multiprocessing, time

#a coroutine
def task1():
   for n in range(5):
      print(n)
      time.sleep(0.01) #cause a small delay

def task2():
   for letter in "ABCDE":
      print(letter)
      time.sleep(0.01) #cause a small delay

if __name__ == "__main__":
   print('Started')

   #create two threads for the tasks
   P1 = multiprocessing.Process(target = task1)
   P2 = multiprocessing.Process(target = task2) 

   P1.start()
   P2.start()

   P1.join()
   P2.join()
   
   P1.close()
   P2.close()

   print('Finished')

See multiprocessing in python.