命名这个 python/ruby 语言结构(使用数组值来满足函数参数)

Posted

技术标签:

【中文标题】命名这个 python/ruby 语言结构(使用数组值来满足函数参数)【英文标题】:Name this python/ruby language construct (using array values to satisfy function parameters) 【发布时间】:2010-11-11 14:34:38 【问题描述】:

这种语言结构叫什么?

在 Python 中我可以说:

def a(b,c): return b+c
a(*[4,5])

得到 9。在 Ruby 中也是如此:

def a(b,c) b+c end
a(*[4,5])

当将单个数组传递给需要多个参数的函数时,这叫什么?

* 运算符的名称是什么?

还有哪些其他语言支持这个很酷的功能?

【问题讨论】:

重复***.com/questions/918449/… @seth:不,不是重复的。您链接到的问题是关于此运算符的 语义 (在 Ruby 中);这个问题是关于术语 【参考方案1】:

Python 文档称之为Unpacking Argument Lists。这是一个非常方便的功能。在 Python 中,您还可以使用双星号 (**) 将字典(散列)解压缩为关键字参数。它们也反向工作。我可以这样定义一个函数:

def sum(*args):
    result = 0
    for a in args:
        result += a
    return result

sum(1,2)
sum(9,5,7,8)
sum(1.7,2.3,8.9,3.4)

将所有参数打包到一个任意大小的列表中。

【讨论】:

我知道这个有一段时间了,也曾盲目使用过一次,但从来没有真正理解过。很好的清晰和简单的解释。 +1 “参数解包”是我一直听到的通用术语。 值得注意的是,**kwargs 特性在 ruby​​ 中没有直接的类比,尽管它几乎可以通过将 Hash 作为最后一个参数来近似。然而,这有一些不同。 我希望我能接受多个答案——感谢 Matthew Schinckel 和 Alex Martelli 回答问题的 Ruby 方面。感谢所有参与的人!【参考方案2】:

在 ruby​​ 中,它通常被称为“splat”。

同样在 ruby​​ 中,您可以用它来表示“列表中的所有其他元素”。

a, *rest = [1,2,3,4,5,6]
a     # => 1
rest  # => [2, 3, 4, 5, 6]

它也可以出现在赋值运算符的任一侧:

a  = d, *e

在这种用法中,有点像scheme的cdr,虽然它不一定是列表的头部。

【讨论】:

splat 运算符是 Ruby 编程语言中使用的术语,据说是由 Matz 共同编写的(创建 Ruby) 在 Python 3 中添加了“列表中的所有其他元素”语法(在分配的左侧有一个带星号的名称)——您的示例无需修改即可工作。此外(在 Python 3 中),星号变量不必是最后一个:a, b, *middle, y, z = range(10) 有效。虽然它不能出现在作业的右侧,但它并不是真正需要的,因为您可以使用l = list(a, *b) 是的,我想我记得读过那个。我仍然在工作中使用 python 2.4-2.6(我怀疑并且会继续这样做)。我刚刚用 ruby​​ 1.8 做了一个测试,*var 必须是列表中的最后一个。 @Miles 它确实有效,但我在文档中或任何地方都找不到它,但在这件事上。也没有解释为什么a, *b = (1,2,3) 产生b==[2,3] 而不是(2,3) @Evpok 规范在这里:python.org/dev/peps/pep-3132 但在大多数情况下,它似乎并没有正确地进入文档,除了在 the reference manual 和 @987654323 中的简短提及@.【参考方案3】:

这方面的典型术语称为“将函数应用于列表”, 或简称“申请”。

见http://en.wikipedia.org/wiki/Apply

自 1960 年成立以来,它就一直在 LISP 中。 很高兴 python 重新发现了它:-

Apply 通常位于 list 或列表的表示形式上,例如 作为一个数组。但是,可以将函数应用于参数 来自其他地方,例如结构。我们的 PARLANSE 语言 具有固定类型(int、float、string、...)和结构。 奇怪的是,函数参数列表看起来很像一个结构 定义,在 PARLANSE 中,它一个结构定义, 并且您可以将 PARLANSE 函数“应用”到兼容的结构中。 您也可以“制作”结构实例,因此:

(定义 S (结构[t整数] [f 浮动] [b(数组布尔值 1 3)] )结构体 ) 定义 (= A (数组布尔值 1 3 ~f ~F ~f)) (= s (make S -3 19.2 (make (array boolean 1 3) ~f ~t ~f)) (定义 foo (函数字符串 S) ...) (foo +17 3e-2 A) ;标准函数调用 (foo s) ;这里是“申请”

PARLANSE 看起来像 lisp 但不是。

【讨论】:

调用可变参数语法“将函数应用于列表”是完全错误的,IMO。对 PARLANSE 的引用似乎也没有任何贡献。 @Thomas:OP 明确表示,“将数组传递给函数以获取多个参数”。不管你喜不喜欢,这就是将函数应用于列表的表示。 OP 还要求其他语言“具有这个很酷的功能”; PARLANSE 示例类似但不同,并作为对比提供。 我认为(像 ThomasH 一样)apply 和 splat/var-args 之间存在显着差异,前者在列表的项目上执行相同的函数 n 次,后者调用该函数一次列表的元素作为参数。 @Matthew:您将“地图”与“应用”混淆了。请参阅此参考:n-a-n-o.com/lisp/cmucl-tutorials/LISP-tutorial-20.html【参考方案4】:

Ruby 将其称为 splat,尽管 David Black 也提出了简洁的 unar,ray 运算符(即 unary unarray operator >)

【讨论】:

【参考方案5】:

我一直称其为“列表扩展”,但我认为这不是标准术语(我认为没有...)。所有版本的 Lisp(包括方案),以及 Haskell 和其他函数式语言,都可以很容易地做到这一点,但我认为在“主流”语言中做到这一点并不容易(也许你可以将其作为“反思”特技在一些!-)。

【讨论】:

我也不知道任何标准术语,但我一直将 '*args' 发音为 'star args' 和 '**kwargs' 'kay word args'。我敢肯定其他人有自己的术语,我很想知道它。【参考方案6】:

Haskell 也有它(配对),带有 uncurry 函数:

ghci> let f x y = 2*x + y
f :: (Num a) => a -> a -> a
ghci> f 1 2
4
ghci> f 10 3
23
ghci> uncurry f (1,2)
4
ghci> uncurry f (10,3)
23

你也可以把它做成一个运算符,这样就更像splat了:

ghci> f `uncurry` (1,2)
4
ghci> let (***) = uncurry
(***) :: (a -> b -> c) -> (a, b) -> c
ghci> f *** (10,3)
23

虽然为 3-tuple、4-tuple 等情况定义类似的函数很容易,但 n-tuples 没有任何通用函数(就像 splat 在其他语言中一样),因为Haskell 的严格类型。

【讨论】:

【参考方案7】:

大部分问题已经回答了,但是对于“*运算符的名称是什么?”这个问题:技术术语是“星号”(来自拉丁词asteriscum,意思是“小星星”,而它又来自希腊语ἀστερίσκος)。不过,它通常会被称为“star”,或者如上所述,“splat”。

【讨论】:

以上是关于命名这个 python/ruby 语言结构(使用数组值来满足函数参数)的主要内容,如果未能解决你的问题,请参考以下文章

最适合照片共享网站的语言:PHP、Python、Ruby 还是其他? [关闭]

java反射机制

java反射机制

为啥脚本语言(例如 Perl、Python、Ruby)不适合作为 shell 语言? [关闭]

java反射学习笔记

浅谈java放射机制