Skip to content
On this page

Decorators

Decorator == function wrapper. For module-level functions these are equivalent sugar:

import time
def time_it(func):
	def now_ms():
		return time.time() * 1000

	def inner():
		start = now_ms()
		ret = func()
		end = now_ms()
		print("perf cost:", end-start, inner)
		return ret
	return inner

# form A: use decorators
@time_it
def final_func_name():
	print("hello world")

# form B: underlying operation
final_func_name = time_it(lambda: print("hello other world"))

Later, see also functools.wraps

List Comprehensions

new_list = [expression for formal_arg_iterator_name in iterable]

# so...
numbers = [1, 2, 3, 4, 5]
squared_numbers = [n**2 for n in numbers]
# squared_numbers will be [1, 4, 9, 16, 25]

official

squares = list(map(lambda x: x**2, range(10)))

# IS
squares = []
for x in range(10):
    squares.append(x**2)

# IS
squares = [x**2 for x in range(10)]

Filtering

basic_syntax = [result_expression for iter_arg in iterable]
filter_syntx = [result_expression for iter_arg in iterable if cond_exp]


numbers = [1, 2, 3, 4, 5]
squared_evens = [n**2 for n in numbers if n%2 == 0]
# [4, 16]

As python's trinary conditional expression is "happy_exp if cond_exp else sad_exp", the result expression can also have a fork:

trunc_to_even = [n-1 if n%2 else n for n in numbers]
# [0, 2, 2, 4, 4]

Nested List Comps, or How We Blew Readability in the Name of Readability

Ah! a single listcomp can have multiple for-iter clauses. (and apparently more than one if-filter clauses??)

out = []
for x in range(1, 10):
	for y in range(2,4):
	 out.append(x+y)
# becomes
out = [x+y for x in range(1,10) for y in range(2,4)]

Variadic Args

def show_args(func):
	def inner(*args, **kwargs):
		print("args:", args)
		print("kwargs:", kwargs)
		return func(*args, **kwargs)
	return inner

@show_args
def do_stuff(*args, **kwargs):
	print("my args:", args)
	print("my kwargs:", kwargs)

do_stuff("foo", "bar", a="b", c="d")

results: args is a tuple, kwargs is a map ({'a': 'b', 'c': 'd'})

String Interpolation

message = "hello world"
print(f"Message was: {message}")

or was this the pep8 direction? print("My arguments are: {0}, {1}".format(arg1,arg2))

Lambdas

  • Py lambdas only have expression mode; there is no anon body-form.
    • (why? because) "the complexity of any proposed solution for this puzzle is immense, to me: it requires the parser (or more precisely, the lexer) to be able to switch back and forth between indent-sensitive and indent-insensitive modes, keeping a stack of previous modes and indentation level. Technically that can all be solved (there's already a stack of indentation levels that could be generalized). But none of that takes away my gut feeling that it is all an elaborate Rube Goldberg contraption." --G
const js_classic = function() {};
const js_fat_arrow_body = () => {console.log("hello")};
const js_fat_arrow_expr = () => console.log("hello");

py_arity0 = lambda: print("hello")
py_arity1 = lambda x: print("hello", x)
py_arityN = lambda x, y, z: print("hello", x, y, z)

Force a closure using an argument with a default value:

x = 42
example = lambda arg=x: return f"meaning of life: {arg}"

While the above is simpler as example = lambda: f"meaning of life: {x}"

formal-arg closures are required reading for this list comp: li = [lambda arg=x: arg * 10 for x in range(1, 5)] which is "create a arity 0 function that returns i*10 for each i in 1 to 5"

(src doc: li = [lambda arg=x: arg * 10 for x in range(1, 5)])

Tuples

Was it this? force a len(1) tuple with (val,)

show asm-like bytecode

dis realpython.com

import dis
add = lambda x, y: x + y
dis.dis(add)

JavaScript/Bash code released under the MIT License.