kuniga.me > Docs > Python Cheatsheet
Python Cheatsheet
Syntax for common tasks I run into often. Assumes Python 3.
Index
Data Structures
Enum
No value
From primitive
To primitive
List
Map over list
Filter list
Any / All
Sort list
Dictionaries
Default entries
Remove entry
Map over dictionary
Sort dictionary
Sets
Create
Insert
Difference
Union
Map over set
Strings
Object Oriented
Class Methods
Inheritance
Instance check
Abstract classes
Dataclasses
Default Value
Cloning
Immutable
Flow Control
Exceptions
Stdin/Stdout
Capture stdout
Files
Read file
Write file
Functions
Force named arguments in call
Decorators
Pass primitive values by reference
Date and Time
Elapsed time
Context Manager
Async
Operating System
Path
Create
Append path
Get filename
File extension
Navigate to parent
Resolve
To String
Subprocess
Other Data Structures
Queue
Regex
Check if it matches
Data Structures
Enum
from enum import Enum
class MyEnum ( Enum ):
A = 'a'
B = 'b'
No value
from enum import Enum , auto
class MyEnum ( Enum ):
A = auto ()
B = auto ()
From primitive
print ( MyEnum ( 'a' )) # MyEnum.A
It does validation:
print ( MyEnum ( 'c' ))
To primitive
print ( MyEnum . A . value ) # 'a'
List
Map over list
xs = [ 1 , 2 , 3 ]
ys = [ f ( x ) for x in xs ]
Filter list
xs = [ 1 , 2 , 3 ]
ys = [ x for x in xs if x % 2 == 0 ]
NOTE: filter and map can be combined into one.
Any / All
Find if any (all) element satisfy a predicate:
xs = [ 1 , 2 , 3 ]
ys = any ( predicate ( x ) for x in xs )
NOTE: this is a generator, so it will short-circuit once if finds an element satisfying the predicate. The version below creates a list first, so no short-circuit happens.
xs = [ 1 , 2 , 3 ]
ys = [ any ( predicate ( x ) for x in xs )]
Sort list
Using default sorting:
>>> sorted ([ 5 , 2 , 3 , 1 , 4 ])
[ 1 , 2 , 3 , 4 , 5 ]
Sorting using key function. For example, sort list of pairs by the second element:
sorted ([[ 1 , 3 ], [ 2 , 2 ], [ 3 , 1 ]], key = lambda x : x [ 1 ])
Sorting by custom comparator:
import functools
# Function that returns
# < 0 if a < b
# > 0 if a > b
# = 0 if a = b
def cmp ( a , b ):
return a - b
sorted ([ 3 , 2 , 1 ], key = functools . cmp_to_key ( cmp ))
Dictionaries
Default entries
from collections import defaultdict
dict = defaultdict ( list )
dict [ 'key' ]. append ( 1 ) # {'key': [1]}
Note: defaultdict
takes a callback to be called when a new entry is added. list
is equivalent to lambda _ : []
.
Remove entry
del dict [ key ]
Map over dictionary
ys = { k : f ( v ) for k , v in xs . items ()}
Sort dictionary
Dictionaries are unordered sets, so you likely want to work with a list after sorting.
d = { 'a' : 3 , 'b' : 2 }
xs = sorted ( d . items (), key = lambda x : x [ 1 ])
Sets
Create
s = { 1 , 2 , 3 }
Empty:
s = set ()
Note that s = {}
creates an empty dictionary.
Insert
Add/insert
s . add ( 4 )
Difference
s1 = set ([ 1 , 2 ])
s2 = set ([ 2 , 3 ])
s1 = s1 - s2 # {1}
Union
s1 = set ([ 1 , 2 ])
s2 = set ([ 2 , 3 ])
s1 = s1 . union ( s2 ) # {1, 2, 3}
Map over set
xs = { 1 , 2 , 3 }
ys = { f ( x ) for x in xs }
Strings
To bytes. Depends on the desired encoding.
bytes = str . encode ( "utf-8" ) # utf-8 is the default
From bytes:
str = bytes . decode ()
Object Oriented
Basic Syntax:
class C :
def __init__ ( self , param ):
self . param
def method ( self ):
return self . param
@ staticmethod
def static_method ():
return 1
Check if object is instance of a class:
class MyClass :
pass
x = MyClass ()
isinstance ( x , MyClass )
Class Methods
Methods where the bound variable is an instance to the class.
class C :
@ classmethod
def class_method ( cls ):
print ( cls ) # __main__.C
def method ( self ):
print ( self ) # <__main__.C instance at 0x12345>;
See also: Class Methods in Revisiting Python: Object Oriented Programming
Inheritance
Example template:
class Base :
def __init__ ( self , f ):
self . f = f
class Child ( Base ):
def __init__ ( self , f , g ):
super (). __init__ ( f )
self . g = g
c = Child ( 1 , 2 )
print ( c . f , c . g )
Instance check
if isinstance ( obj , MyClass ):
print ( "is of type MyClass" )
Abstract classes
from abc import ABC , abstractmethod
class MyAbstractClass ( ABC ):
@ abstractmethod
def my_abstract_method ( self , arg1 , arg2 ):
"""Describe this method. No need to have body"""
class MyConcreteClass ( MyAbstractClass ):
def my_abstract_method ( self , arg1 , arg2 ):
return arg1 + arg2
c = MyConcreteClass ()
# TypeError: Can't instantiate abstract class MyNonConcreteClass
# with abstract method my_abstract_method
d = MyNonConcreteClass ()
Dataclasses
Lightweight syntax for creating classes / records.
from dataclasses import dataclass
@ dataclass
class Point :
x : int
y : int
p = Point ( 10 , 20 )
print ( p . x ) # 10
q = Point ( y = 10 , x = 20 )
print ( q . x ) # 20
Complex types:
# ... continued from above
@ dataclass
class Polygon :
pts : [ Point ]
pol = Polygon ([ p , q ])
print ( pol . pts ) # [Point(x=10, y=20), Point(x=20, y=10)]
Default Value
@ dataclass
class Point :
x : int
y : int
z : int = 0
p = Point ( x = 10 , y = 20 )
print ( p . z ) # 0
Cloning
dataclasses.replace
:
p = Point ( 1 , 2 )
p_copy = dataclasses . replace ( p )
Immutable
Prevents fields from being changed:
@ dataclass ( frozen = True )
class Wrapper :
v : str = 'abc'
def __init__ ( self ):
self . v = 'cde' # error
w = Wrapper ()
w . v = 'cde' # error
It’s possible to bypass though:
@ dataclass ( frozen = True )
class Wrapper :
v : str = 'abc'
def __init__ ( self ):
# internal backdoor
object . __setattr__ ( self , "v" , "backdoor" )
w = Wrapper ()
# external backdoor
object . __setattr__ ( w , "foo" , 'backdoor' )
Flow Control
Exceptions
Basic syntax:
try :
raise Exception ( 'hello' )
except Exception as ex :
print ( 'caught' , str ( ex ))
Custom exception:
class MyException ( Exception ):
pass
try :
raise MyException ( 'hello' )
except MyException as ex :
print ( 'caught specific' , str ( ex ))
Re-raise exception
try :
raise Exception ( 'hello' )
except Exception as ex :
print ( 'caught specific' , str ( ex ))
raise
Raise new exception but preserve original stack trace:
try :
raise Exception ( 'hello' )
except Exception as ex :
raise Exception ( 'new title' ) from ex
Stdin/Stdout
Capture stdout
out = io . StringIO ()
with redirect_stdout :
# call code which prints to stdout
execute ()
stdout_str = out . getValue ()
Files
Read file
with open ( filename , "r" ) as file :
print ( file . readlines ())
Read all the contents into one string:
with open ( filename , "r" ) as file :
print ( file . read ())
Write file
Temporary file:
# Note: file gets deleted once it exits the scope
with tempfile . NamedTemporaryFile () as file :
file . write ( "Hello World \n " )
print ( f "writing to filename = { file . name } " )
# make sure to flush if something will read from it
file . flush ()
# read as bytes
file . read ()
Note: default mode is w+b
(write and bytes). If you’ll be reading strings, make sure to change to mode=w+
.
Functions
Force named arguments in call
def f ( * , a , b ):
pass
f ( a = 1 , b = 2 ) # ok
f ( 1 , 2 ) # error
Decorators
A decorator is basically a function transformer. Basic template:
import functools
def my_decorator ( f ):
@ functools . wraps ( f )
def wrapper ( * args , ** kwargs ):
# pre-process
...
r = f ( * args , ** kwargs )
# post-process
...
return r
return wrapper
@ my_decorator
def my_func ():
pass
Pass primitive values by reference
Primitives like bool
, int
, str
, etc. are not implicitly bound to functions in the same scope like list
s are. Declaring it nonlocal
binds it explicitly.
def f ():
x = 0
def inc ():
nonlocal x
x += 1
inc ()
print ( x ) # 1
Date and Time
Current time:
datetime . now ()
Adding/subtracting time:
datetime . now () + datetime . timedelta ( days = 1 )
Elapsed time
Wall-clock time in seconds:
start = time . time ()
call ()
elapsed_secs = time . time () - start
Context Manager
class ContextManager :
def __enter__ ( self ):
self . v = [ 1 , 2 , 3 ]
return self
def __exit__ ( self , exc_type , exc_value , traceback ):
self . v = None
return self
def foo ( self ):
print ( len ( self . v ))
with ContextManager () as ctx :
ctx . foo ()
Async
class ContextManager :
async def __aenter__ ( self ):
self . v = [ 1 , 2 , 3 ]
return self
async def __aexit__ ( self , exc_type , exc_value , traceback ):
self . v = None
return self
async def foo ( self ):
print ( len ( self . v ))
async with ContextManager () as ctx :
await ctx . foo ()
Operating System
Path
from pathlib import Path
Create
p = Path ( '/etc' )
Append path
p = p / 'dir' # Path('/etc/dir')
Note the overloaded operator /
. Works with files too:
p = p / 'file.txt' # Path('/etc/file.txt')
Get filename
Path ( '/home/file.txt' ). name # 'file.txt'
Note: this also returns the leaf directory:
Path ( '/home/me/' ). name # 'me'
File extension
It includes the .
.
Path ( '/home/me/file.txt' ). suffix # '.txt'
Navigate to parent
p = Path ( '/dev/null' ). parent # Path('dev/')
Resolve
p = Path ( '.' ). resolve () # absolute path
To String
print ( str ( Path ( '/dev/null' ))) # dev/null
Subprocess
import subprocess
Run command, get stdout:
command = [ 'ls' , '-l' ]
res = subprocess . run ( command , close_fds = True , stdout = subprocess . PIPE )
output = res . stdout . decode ()
Check return code:
res = subprocess . run ( command , close_fds = True , stdout = subprocess . PIPE )
print ( res . returncode )
Other Data Structures
Queue
The Queue
class is an advanced implementation that can be used for example in multi-thread applications. We can still use it as a plain queue data structure.
from queue import Queue
# Create
q = Queue ()
# Insert back
q . put ( item )
# Retrieve and remove front
first = q . get ()
# Front element without removing
first = q [ 0 ]
# Size
# Queue doesn't expose len()
# since it can lead to incorrect
# usage in multi-threaded applications
# Is empty?
q . empty ()
Regex
Keywords: regular expression
Check if it matches
text = "the number is 12345"
if re . match ( 'is ([0-9]+)' , text ):
print ( "matches" )
text = "the number is 12345"
result = re . search ( 'is ([0-9]+)' , text , re . IGNORECASE )
if result :
print ( result . group ( 1 )) # 12345