Faster Python - tips and examples
A collection of tips and tricks to speed up your Python code.
- Use pathlib instead of os
- Use NumPy for arrays
- Use built in functions
- Importing libraries
- String formatting
- String concatenation
- Nested iteration
- Initialization of lists and dictionaries
Each section includes timed examples sorted from slowest to fastest.
import pathlib
import os
directory = "parent/child/"
new_folder = "folder"
new_file = "file.txt"
Joining pathname components
%timeit os.path.join(directory, new_folder, new_file)
%timeit str(pathlib.Path(directory) / new_folder / new_file)
Get the current working directory
%timeit os.getcwd()
%timeit pathlib.Path.cwd()
Find the basename for a path
%timeit os.path.basename("/path/file.suffix")
%timeit pathlib.Path("/path/file.suffix").name
import math
import numpy as np
a = range(10000)
%timeit [i**2 for i in a]
%timeit [math.pow(i, 2) for i in a]
%timeit np.square(np.array(a))
%timeit [i**0.5 for i in a]
%timeit [math.sqrt(i) for i in a]
%timeit np.sqrt(np.array(a))
Note: If you apply a math function using a builtin function like "map" it might be even faster than NumPy!
%timeit list(map(math.sqrt, a))
words = ["one", "two", "three"] * 1000
def loop_apply(words):
L = []
for word in words:
L.append(word.upper())
def list_comprehension_apply(words):
[i.upper() for i in words]
def map_apply(words):
list(map(str.upper, words))
%timeit loop_apply(words)
%timeit list_comp_apply(words)
%timeit map_apply(words)
%timeit from math import sqrt; sqrt(50)
%timeit import math; math.sqrt(50)
%timeit from numpy import square; square(2)
%timeit import numpy; numpy.square(2)
Note: When importing a larger library, like Pandas, gains can be minimal or even slower.
%timeit import pandas; pandas.DataFrame()
%timeit from pandas import DataFrame; DataFrame()
%timeit str(12) + " is a number"
%timeit "{} is a number".format(12)
%timeit "%s is a number" % (12)
%timeit f"{12} is a number"
Note: %s formatting can be better for readability of longer strings.
long_string = (
"This is a slightly longer string that needs %s, %s, %s, and %s in it."
% (123, 456, 789, 101112)
)
long_string = f"This is a slightly longer string that needs {123}, {456}, {789}, and {101112} in it."
%%timeit
output = ""
for word in words:
output += word
%%timeit
output = "".join(words)
import itertools
a = range(100)
def nested_for_loop(a, b, c):
L = []
for i in a:
for j in b:
for k in c:
L.append((i, j, k))
def nested_itertools(a, b, c):
L = []
for p in itertools.product(a, b, c):
L.append(p)
def nested_list_comprehension(a, b, c):
L = [(i, j, k) for i in a for j in b for k in c]
%timeit nested_for_loop(a, a, a)
%timeit nested_itertools(a, a, a)
%timeit nested_list_comprehension(a, a, a)
%timeit list()
%timeit []
%timeit dict()
%timeit {}