beo*_*ver 38 python arguments partial-application
以python内置pow()函数为例.
xs = [1,2,3,4,5,6,7,8]
from functools import partial
list(map(partial(pow,2),xs))
>>> [2, 4, 8, 16, 32, 128, 256]
Run Code Online (Sandbox Code Playgroud)
但是我如何将xs提高到2的幂?
要得到 [1, 4, 9, 16, 25, 49, 64]
list(map(partial(pow,y=2),xs))
TypeError: pow() takes no keyword arguments
Run Code Online (Sandbox Code Playgroud)
我知道列表理解会更容易.
Eri*_*ric 36
partial.args
在最左边的将被前置到位置参数位置参数
您可以随时"修复" pow以获得关键字参数:
_pow = pow
pow = lambda x, y: _pow(x, y)
Run Code Online (Sandbox Code Playgroud)
kos*_*sii 13
我想我只是使用这个简单的单线程:
import itertools
print list(itertools.imap(pow, [1, 2, 3], itertools.repeat(2)))
Run Code Online (Sandbox Code Playgroud)
更新:
我还提出了一个比有用的解决方案更有趣的方法.它是一个美丽的语法糖,从Python3 中的...字面意思Ellipsis中获益.它是一个修改版本partial,允许省略最左边和最右边的一些位置参数.唯一的缺点是你不能再传递省略号作为参数.
import itertools
def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = keywords.copy()
newkeywords.update(fkeywords)
return func(*(newfunc.leftmost_args + fargs + newfunc.rightmost_args), **newkeywords)
newfunc.func = func
args = iter(args)
newfunc.leftmost_args = tuple(itertools.takewhile(lambda v: v != Ellipsis, args))
newfunc.rightmost_args = tuple(args)
newfunc.keywords = keywords
return newfunc
>>> print partial(pow, ..., 2, 3)(5) # (5^2)%3
1
>>> print partial(pow, 2, ..., 3)(5) # (2^5)%3
2
>>> print partial(pow, 2, 3, ...)(5) # (2^3)%5
3
>>> print partial(pow, 2, 3)(5) # (2^3)%5
3
Run Code Online (Sandbox Code Playgroud)
所以原始问题的解决方案将是这个版本的部分 list(map(partial(pow, ..., 2),xs))
nro*_*rob 11
为什么不创建一个快速的lambda函数来重新排序args和partial
partial(lambda p, x: pow(x, p), 2)
Run Code Online (Sandbox Code Playgroud)
您可以为此创建一个辅助函数:
from functools import wraps
def foo(a, b, c, d, e):
print('foo(a={}, b={}, c={}, d={}, e={})'.format(a, b, c, d, e))
def partial_at(func, index, value):
@wraps(func)
def result(*rest, **kwargs):
args = []
args.extend(rest[:index])
args.append(value)
args.extend(rest[index:])
return func(*args, **kwargs)
return result
if __name__ == '__main__':
bar = partial_at(foo, 2, 'C')
bar('A', 'B', 'D', 'E')
# Prints: foo(a=A, b=B, c=C, d=D, e=E)
Run Code Online (Sandbox Code Playgroud)
免责声明:我没有使用关键字参数对此进行测试,因此它可能因某种原因而爆炸.此外,我不确定这是否@wraps应该用于,但它似乎是正确的.
你可以使用一个闭包
xs = [1,2,3,4,5,6,7,8]
def closure(method, param):
def t(x):
return method(x, param)
return t
f = closure(pow, 2)
f(10)
f = closure(pow, 3)
f(10)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12195 次 |
| 最近记录: |