noumenal noumenal - 1 year ago 37
Python Question

Is there a shorthand for repeated reassignment of a variable?

Consider the example:

x = 27
x = sqr(x)
x += 2
x = x * 0.1

This could trivially be reduced to

x = 0.1 * (sqr(27) + 2)

Now, consider (x as an OrderedDict)

x = {k: bubble_sort(v) for k, v in x.items()}

x = {k: rename(k) for k, v in x.items()}

x = {k: abs(k) for k, v in x.items()}

Is there a shorthand trick to avoid repeating the variable assignment? For example, is there a function such that:

def pipeline(x, function_handles):
for f in function_handles:
x.apply(f) #in place
return x


def pipeline(x, expression):
for ex in expression:
ex(x) #in place
return x

Answer Source

In the operator module there is the operator.methodcaller function. It works like itemgetter, which is the one you are most likely to have already seen: given a name, the return value of methodcaller is partial function that calls the named method of its argument.

That is, given:

x = SomeObjectType()
f = operator.methodcaller('amethod', 'arg1', arg2=100)

Is the same as saying:

x = SomeObjectType()
x.amethod('arg1', arg2=100)

You could use this along with simple lambda expressions and/or functools.partial or partial_method to construct a list of functions/methods to be applied. Then, as @cricket_007 suggested, you could use or write code to automatically apply them.

Also of note is functools.reduce. You can write or construct a caller function, and then use reduce to supply it with a list of functions to call.

Here's some code to reduce a list of functions against a list of data (py3, but works in 2.7):

import functools
import itertools
import operator

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

def apply(val, fn):
    print("F=",fn, "val=",val)
    return fn(val)

from functools import reduce

fns = [sorted,

print(reduce(apply, fns, data))