Collection of Python snippets
On-going list of niche snippets for programming Python like an annoying know-it-all (also some actual good tips).
Use underscores in numbers
Underscores in numbers are ignored, but can increase readability:
2_000_000 == 2000000
Use underscores to discard returns
Use underscores to ignore return elemens. More advanced, use can use a wildcard *
to discard a sub-set of the return arguments:
def some_function():
…
return a, b, c, d
a, _, c, d = func()
a, *_, d = func()
Check for any of list of types
if isinstance(variable, (int, float)):
# …
Use default if is None
Instead of:
def func(var = None):
if var is None:
var = "DEFAULT"
you can do:
def func(var = None):
var = var or "DEFAULT"
Use type in add_argument
to directly transform input
A pattern I use a lot in ArgumentParser
is to abuse the type
argument. As the input argument is just casted by calling the type
object you can also just give a function to transform the input. For example a config file:
from argparse import ArgumentParser
import json
parser = ArgumentParser()
parser.add_argument("--config", type=lambda x: json.load(open(x, 'r')))
args = parser.parse_args()
args.config # is now the loaded config file already!
Unpack namespace as keyword arguments
Assume you have an argument parser that matches the arguments of the main function and just want them put in:
from argparse import ArgumentParser
def main(file: str, name: str):
pass
parser = ArgumentParser()
parser.add_argument("--file")
parser.add_argument("--name")
with vars
you can make the Namespace
a dict and unpack it in one statement:
main(**vars(parser.parse_args()))
Implicit infinite defaultdict
Lets say you want to set
dictionary["level1"]["level2"]["arg"]["attr"] = some_value
without having to define any of the levels. Make a infinite defaultdict:
from collections import defaultdict
infinite_defaultdict = defaultdict(lambda: infinite_defaultdict)
dictionary = infinite_defaultdict()
dictionary["level1"]["level2"]["arg"]["attr"] = some_value
global vs nonlocal
Use the keyword nonlocal
to access the index
variable in the outer function but not the global variable which you would access with global
.
index = 0
def outer_function():
index = 42
def inner_fucntion():
nonlocal index
index += 1
inner_function()
Using slash with pathlib
Paths
The /
operator is overloaded for pathlib
so you can easily extend paths:
from pathlib import Path
path = Path("/home/morris")
code_path = path / "code"
code_path == Path("/home/morris/code")
Iterate over only folders in a folder
from pathlib import Path
for folder in filter(Path.is_dir, Path(path).iterdir()):
pass
Use product to reduce nested for loops
# instead of
for i in range(N):
for j in range(N):
pass
# you can do
from itertools import product
for i, j in product(range(N), range(N)):
pass
Generate a random list of words
import random
def random_words(n: int) -> list[str]:
return random.sample(open("/usr/share/dict/words").read().splitlines(), n)
def some_function():
some_function.attribure =