noumenal - 7 months ago 14

Python Question

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

or

`def pipeline(x, expression):`

....

for ex in expression:

ex(x) #in place

return x

Answer

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)
f(x)
```

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):

```
#!python3
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,
max,
str,
]
print(reduce(apply, fns, data))
```