6

I want to use partial from functools to partially apply a function's second argument, I know it is easy to do with lambda rather than partial as follows

>>> def func1(a,b):
...     return a/b
...
>>> func2 = lambda x:func1(x,2)
>>> func2(4)
2

but I strictly want to use partial here (for the sake of learning) so i came up with this.

>>> def swap_binary_args(func):
...     return lambda x,y: func(y,x)
...
>>> func3 = partial(swap_binary_args(func1),2)
>>> func3(4)
2

Is it possible to extend this strategy to a level where I can partial apply any arguments at any place like in the following pseudocode

>>>def indexed_partial(func, list_of_index, *args):
...     ###do_something###
...     return partially_applied_function

>>>func5=indexed_partial(func1, [1,4,3,5], 2,4,5,6)

in our case I can use this function as follows

>>>func6=indexed_partial(func1, [1], 2)

Is it possible to have an indexed partial like I want ? is there anything similar to this already which I am not aware of ? and more importantly is the idea of indexed partial generally a good or bad idea why ?

This question has been marked as possible duplicate of Can one partially apply the second argument of a function that takes no keyword arguments? in that question the OP asked is it possible to partially apply second argument but here i am asking how to cook a function that can partially apply any arbitrary argument

Community
  • 1
  • 1
Kavin Eswaramoorthy
  • 1,595
  • 11
  • 19
  • 4
    Have you considered just using named arguments? `functools.partial` allows for them, and that's how you'd handle this in real code, although maybe it won't suit your exercise. – jwilner Apr 09 '15 at 22:28
  • 1
    You could probably cook something up using `inspect.getargspec` and binding using arg names. – tzaman Apr 09 '15 at 22:36
  • @jwilner partial with keyword argument would be virtually equivalent to what i am trying to achieve, instead of using index I should use keys. Thanks :) – Kavin Eswaramoorthy Apr 09 '15 at 22:40
  • possible duplicate of [Can one partially apply the second argument of a function that takes no keyword arguments?](http://stackoverflow.com/questions/11173660/can-one-partially-apply-the-second-argument-of-a-function-that-takes-no-keyword) – Reut Sharabani Apr 09 '15 at 22:41
  • I have a (rudimentary) solution but as been indicated, it can't be done with `partial`. – emvee Apr 09 '15 at 23:25

1 Answers1

1

I, too, think what you ask can't be done (easily?) with functools.partial. Probably the best (and most readable) solution is to use partial with keyword-arguments. However, in case you want to use positional arguments (and hence indexed partial arguments), here is a possible definition of indexed_partial:

def indexed_partial(func, list_of_index, *args):
    def partially_applied_function(*fargs, **fkwargs):
        nargs = len(args) + len(fargs)
        iargs = iter(args)
        ifargs = iter(fargs)
        posargs = ((ifargs, iargs)[i in list_of_index].next() for i in range(nargs))
        return func(*posargs, **fkwargs)
    return partially_applied_function
davidedb
  • 867
  • 5
  • 12