给定具有两个参数的函数f,如何标准地只将map应用于x?
def f (x,y):
print x,y
更具体地说,我想在一行中使用map执行以下操作。list=[1,2,3]
fixed=10
for s in list:
f(s,fixed)
实现这个目标的一种方法是:
import functools
map(functools.partial(lambda x,y:f(y,x),fixed),list)
有更好的方法吗?
给定具有两个参数的函数f,如何标准地只将map应用于x?
def f (x,y):
print x,y
更具体地说,我想在一行中使用map执行以下操作。list=[1,2,3]
fixed=10
for s in list:
f(s,fixed)
实现这个目标的一种方法是:
import functools
map(functools.partial(lambda x,y:f(y,x),fixed),list)
有更好的方法吗?
首先,没有必要同时使用lambda和partial——它们是可替代的:
map(lambda x:f(x,fixed),srclist)
其次,只要你知道参数的名称,你可以使用 partial
绑定第二个参数:
map(functools.partial(f,y=fixed),srclist)
或者,使用列表推导式:
[f(x, fixed) for x in srclist]
给定以下具有两个参数的函数f,如何标准地将map应用于仅x?
关于柯里化和部分应用的讨论
从FP角度来看,您的函数f
是"未柯里化"的 - 虽然它在概念上接受两个参数,但它们被捆绑在一个单一的产品结构中。在Python中,所有东西都是未柯里化的。您必须一次性提供所有参数或不提供任何参数。
为了解决这个问题,有各种技巧,但在概念上,您只想“柯里化”该函数。也就是说,将f(x,y)
转换为返回新函数g(y)
的f(x)
。
在默认为柯里化的语言中,您可以轻松编写此翻译:
-- curry: take a function from (x,y) to one from x to a function from y to z
curry :: ((x,y) -> z) -> (x -> y -> z)
curry f x y = f (x, y)
curry
接受你的咖喱化的 f
和它的参数,分别地,并在所有参数都可用时应用这些参数。相反的操作也很容易:uncurry :: (x -> y -> z) -> ((x,y) -> z)
uncurry f (x,y) = f x y
这与部分应用有什么关系?
在非柯里化语言中,每个参数都可以依次应用(例如,部分地,关于函数的arity)。在柯里化语言中,您必须首先玩一些技巧来取消柯里化函数,就像上面的例子一样。
我认为在默认情况下处于柯里化环境中更加灵活,因为部分应用是免费的。在这样的环境中,常见的是将修改数据结构为管道的函数链接在一起。例如,整数修改的管道:
(+1) . (*2) . (^3) $ 7
它只是一系列部分应用的、非科里化函数,每个函数都组合起来,作用于前一个函数的输出。这很好,因为它在视觉上分离了关注点。
map(lambda x: f(fixed,x), thelist)
或者干脆不使用 map()
,改用列表推导式。
[f(fixed, x) for x in thelist]
PS:不要使用list
作为变量名,这是一个重要的内置名称(列表类型)。
以下是有关以下代码的解释:
def add(x, y):
return x + y
l = [1, 2, 3]
from functools import partial
plus10 = map(partial(add, y=10), l)
print plus10
## [11, 12, 13]