1

splatter在此 Python 代码中考虑:

def splatter(fn):
    return lambda (args): fn(*args)

def add(a, b):
    return a + b

list1 = [1, 2, 3]
list2 = [4, 5, 6]
print map(splatter(add), zip(list1, list2))

在 n 个压缩序列上映射一个 n 元函数似乎是一个足够常见的操作,可能已经有一个名称,但我不知道在哪里可以找到它。它模糊地唤起了柯里化,似乎还有其他相关的以争论为中心的 HOF,我从未听说过。有谁知道这是否是“众所周知”的功能?在讨论它时,我目前被问题标题中使用的尴尬语言所困扰。

编辑

哇,Pythonmap会自动执行此操作。你可以写:

map(add, list1, list2)

它会做正确的事,为您省去splatter编写函数的麻烦。唯一的区别是zip返回一个列表,其长度是其最短参数的长度,而map用 .extends 扩展较短的列表None

4

2 回答 2

1

我认为zipWith是您正在搜索的功能(这个名称至少在 Haskell 中使用)。它甚至更笼统。在 HaskellzipWith中定义如下(第一行只是类型):

zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
zipWith _ _      _      = []

你的例子就像

zipWith (+) [1, 2, 3] [4, 5, 6]

由于我对python不太了解,我只能指向“ zipWith Analog in Python? ”。

于 2013-03-11T06:30:41.353 回答
0

我在我的“问题”列表中随机看到了这个,并且很惊讶我现在知道了答案。

我问的函数有两种解释。

第一个是我的意图:采用一个接受固定数量参数的函数并将其转换为一个将这些参数作为固定大小列表或元组的函数。在 Haskell 中,执行此操作的函数称为uncurry.

uncurry :: (a -> b -> c) -> ((a, b) -> c)

(为了清楚起见,额外的括号。)

很容易想象将其扩展到具有两个以上参数的函数,尽管它不能在 Haskell 中表达。但是uncurry3,uncurry4等不会不合适。

所以我是对的,它“模糊地唤起了咖喱”,因为它实际上是相反的。


第二种解释是采用一个带有有意可变数量参数的函数并返回一个采用单个列表的函数。

因为splat它在 Python 中作为一个语法结构非常奇怪,所以这很难推理。

但是,如果我们想象一下 JavaScript,它有一个用于“喷溅”的一流命名函数:

varFn.apply(null, args)

var splatter = function(f) {
    return function(arg) {
        return f.apply(null, arg);
    };
};

然后我们可以将其改写为“ apply”函数的部分应用:

var splatter = function(f) {
    return Function.prototype.apply.bind(f, null);
};

或者使用下划线partial,我们可以得出无点定义:

var splatter = _.partial(Function.prototype.bind.bind(Function.prototype.apply), _, null)

是的,那是一场噩梦。

_.partial(我认为,需要定义某种帮助程序的替代方法swap会变得更不可读。)

所以我认为这个操作的名称只是“部分应用apply”,或者在 Python 的情况下,它几乎就像 splat 运算符的一部分——如果 splat 是一个“实际的”运算符。


但是,正如克里斯指出的那样uncurry,原始问题中,zip和的特定组合map正是如此。事实上,HLint默认包含一个规则,用一次调用来替换这个复杂的结构。zipWithzipWith


我希望这能解决问题,过去的伊恩。

于 2016-03-04T19:45:13.820 回答