python中是否有内置的身份函数?

rds*_*rds 132 python python-2.7 python-3.x

我想指出一个什么都不做的函数:

def identity(*args)
    return args
Run Code Online (Sandbox Code Playgroud)

我的用例是这样的

try:
    gettext.find(...)
    ...
    _ = gettext.gettext
else:
    _ = identity
Run Code Online (Sandbox Code Playgroud)

当然,我可以使用identity上面定义的,但内置肯定会运行得更快(并避免我自己引入的错误)​​.

显然,mapfilter使用None的身份,但这是具体到它们的实现.

>>> _=None
>>> _("hello")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
Run Code Online (Sandbox Code Playgroud)

rds*_*rds 90

进行更多的研究,没有,在问题1673203中问了一个功能而且Raymond Hettinger表示不会:

最好让人们编写自己的琐碎传递,并考虑签名和时间成本.

所以更好的方法是实现(lambda避免命名函数):

_ = lambda *args: args
Run Code Online (Sandbox Code Playgroud)
  • 优点:获取任意数量的参数
  • 缺点:结果是参数的盒装版本

要么

_ = lambda x: x
Run Code Online (Sandbox Code Playgroud)
  • 优点:不会更改参数的类型
  • 缺点:只需1个位置参数

  • 请注意,这不是身份功能. (13认同)
  • 很好的答案.但是,在获取多个参数时,真正的身份函数会返回什么? (7认同)
  • @Marcin:两个都没有,只是按照他在问题中提出的要求. (5认同)
  • 是的,谢谢,我有一个简单的`lambda x:x`标识函数,适用于一个字符串参数.@Marcin我希望我能做`lambda*args:*args` :-) (4认同)
  • @Marcin 感谢您的评论。为了不误导任何人,我添加了两者的优点/缺点。现在,我真的相信应该有一个内置函数可以接受任意数量的参数并且是一个真实的身份:) (2认同)

Pau*_*ore 23

https://en.wikipedia.org/wiki/Identity_function中定义的标识函数采用单个参数并将其保持不变:

def identity(x):
    return x
Run Code Online (Sandbox Code Playgroud)

你要签名什么你问,当你说的def identity(*args)不是严格意义上的标识功能,只要你想它采取多个参数.这很好,但是你遇到了一个问题,因为Python函数没有返回多个结果,所以你必须找到一种方法将所有这些参数塞进一个返回值.

在Python中返回"多个值"的常用方法是返回值的元组 - 从技术上讲,它是一个返回值,但它可以在大多数上下文中使用,就好像它是多个值一样.但这样做意味着你得到

>>> def mv_identity(*args):
...     return args
...
>>> mv_identity(1,2,3)
(1, 2, 3)
>>> # So far, so good. But what happens now with single arguments?
>>> mv_identity(1)
(1,)
Run Code Online (Sandbox Code Playgroud)

并且快速解决这个问题会带来其他问题,正如这里的各种答案所示.

因此,总之,Python中没有定义身份函数,因为:

  1. 正式定义(单个参数函数)不是那么有用,并且写起来很简单.
  2. 将定义扩展为多个参数通常没有明确定义,并且您最好定义自己的版本,以适合您的特定情况.

对于您的确切情况,

def dummy_gettext(message):
    return message
Run Code Online (Sandbox Code Playgroud)

几乎可以肯定你想要的东西 - 一个具有相同调用约定并返回的函数gettext.gettext,它返回其参数不变,并且清楚地命名以描述它的作用以及它的用途.如果表演在这里是一个至关重要的考虑因素,我会非常震惊.

  • @Max,根据您的建议 `_ = lambda *args: args if len(args)&gt;1 else args[0]`,调用 `_((1,2))` (带有一个元组参数!)将产生 ` (1,2)`,这与调用 `_(1,2)` (带有两个整数参数)的结果相同。因此,您的函数不是单射的:您无法从输出中判断输入是什么。对于身份函数来说,这是一个相当不明确的状态。(它应该是双射的,包括单射性。) (4认同)

tba*_*ack 20

你的工作会很好.当参数的数量修复时,你可以使用这样的匿名函数:

lambda x: x
Run Code Online (Sandbox Code Playgroud)

  • 你也可以使用varargs:`lambda*args:args`.这真的是一种风格选择. (8认同)
  • @delnan:你说它是一种风格选择,它错误地暗示了两种形式的语义没有区别. (8认同)
  • @delnan @rds - `*args`版本有不同的返回类型,因此即使对于单参数情况它们也不相同. (4认同)
  • @Marcin:如果我暗示这一点,那就很不幸了。我的意思是对于这样简单的函数在“def”和“lambda”之间进行选择。 (2认同)

Ser*_*kov 10

Python 中没有内置的标识函数。对Haskellid函数的模仿是:

identity = lambda x, *args: (x,) + args if args else x
Run Code Online (Sandbox Code Playgroud)

用法示例:

identity(1)
1
identity(1,2)
(1, 2)
Run Code Online (Sandbox Code Playgroud)

由于identity除了返回给定的参数之外什么都不做,我认为它不会比本机实现慢。


Mar*_*cin 5

不,没有。

请注意,您的identity

  1. 等价于lambda * args:args
  2. 将装箱参数-即

    In [6]: id = lambda *args: args
    
    In [7]: id(3)
    Out[7]: (3,)
    
    Run Code Online (Sandbox Code Playgroud)

因此,lambda arg: arg如果您需要真正的身份功能,则可能要使用。

注意:此示例将隐藏内置id函数(您可能永远不会使用)。

  • 请注意,id 是一个内置函数,此代码片段将覆盖它。 (2认同)

小智 5

如果速度不重要,这应该可以处理所有情况:

def identity(*args, **kwargs):
    if not args:
        if not kwargs:
            return None
        elif len(kwargs) == 1:
            return  next(iter(kwargs.values()))
        else:
            return (*kwargs.values(),)
    elif not kwargs:
        if len(args) == 1:
            return args[0]
        else:
            return args
    else:
        return (*args, *kwargs.values())
Run Code Online (Sandbox Code Playgroud)

使用示例:

print(identity())
None
$identity(1)
1
$ identity(1, 2)
(1, 2)
$ identity(1, b=2)
(1, 2)
$ identity(a=1, b=2)
(1, 2)
$ identity(1, 2, c=3)
(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)