Python 函数定义与Lambda表达式
鉴于这两个片段:Python 函数定义与Lambda表达式,python,Python,鉴于这两个片段: def sex (code): return {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code] 及 实际的区别是什么?他们有不同的行为吗 最重要的是:一个比另一个更受欢迎吗 我问这个问题,因为我在这个论坛上的一个答案,提供了两种可能性,被另一个用户截短了,修改了,删除了lambda术语。修改的原因是lambda表达式的最后一个选项比函数定义更差。这让我想知道: 为什么lambda表达式比函数定义更糟糕
def sex (code):
return {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code]
及
实际的区别是什么?他们有不同的行为吗
最重要的是:一个比另一个更受欢迎吗
我问这个问题,因为我在这个论坛上的一个答案,提供了两种可能性,被另一个用户截短了,修改了,删除了lambda术语。修改的原因是lambda表达式的最后一个选项比函数定义更差。这让我想知道:
为什么lambda表达式比函数定义更糟糕?特别是像这样简单的。lambda和返回相同内容的def在功能上没有区别。它们完全相同并且具有相同的字节码
>>> def sex (code):
... return {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code]
>>> sex2 = lambda code: {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code]
>>> sex.__code__.co_code == sex2.__code__.co_code
True
我想说,从一般意义上说,任何一种编写函数的方法都更糟糕,这是错误的。但是,在您的示例中,def版本更好。原因是lambdas的一般用途是在表达式中简洁地编写简短的匿名函数。做name=lambda:….没有真正的意义。。。。如果要立即为匿名函数命名,则没有理由定义它
lambdas的要点是,您可以执行某些FuncRequiringCallbackLambda x:x+1操作,在这种情况下,您不希望为函数指定名称或将其用于除此情况之外的任何用途。如果您确实希望在多个上下文中使用函数,只需使用常规def来定义它。lambda和返回相同内容的def之间没有功能上的区别。它们完全相同并且具有相同的字节码
>>> def sex (code):
... return {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code]
>>> sex2 = lambda code: {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code]
>>> sex.__code__.co_code == sex2.__code__.co_code
True
我想说,从一般意义上说,任何一种编写函数的方法都更糟糕,这是错误的。但是,在您的示例中,def版本更好。原因是lambdas的一般用途是在表达式中简洁地编写简短的匿名函数。做name=lambda:….没有真正的意义。。。。如果要立即为匿名函数命名,则没有理由定义它
lambdas的要点是,您可以执行某些FuncRequiringCallbackLambda x:x+1操作,在这种情况下,您不希望为函数指定名称或将其用于除此情况之外的任何用途。如果要跨多个上下文使用函数,只需使用常规定义即可。简单lambda不一定比嵌套函数差,而且不,这两个示例之间除了语法没有区别,但这种情况可能更简单:
sex = {'m': 'masculino', 'f': 'femenino', '': 'ignorado'}
然后使用sex.\uuuu getitem\uuuuu.简单lambda并不一定比嵌套函数差,而且不,这两个示例之间没有区别,只是语法不同,但这种特殊情况可能更简单:
sex = {'m': 'masculino', 'f': 'femenino', '': 'ignorado'}
然后使用sex.\uu getitem\uuu.除了中提供的信息之外,您会发现许多Python程序员坚持总是使用def而不是lambda,因此我将尝试解释这是为什么 基本上可以归结为以下几行: 应该有一种——最好只有一种——显而易见的方法来做到这一点 Guido是Python的创建者,其中引用了以下内容: 为什么要放弃lambda?大多数Python用户不熟悉Lisp或Scheme,因此名称容易混淆;此外,还有一个广泛的误解,即lambda可以做嵌套函数不能做的事情-我仍然记得Laura Creighton的《啊哈-我给她看了之后,她觉得没什么区别!即使有一个更好的名字,我认为将这两个选择并列只需要程序员考虑做出与他们的程序无关的选择;没有选择可以简化思维过程。而且,一旦map、filter和reduce都消失了,就没有很多地方真正需要编写非常短的局部函数;Tkinter回调出现在我的脑海中,但我发现回调通常应该是一些状态承载对象的方法,但玩具程序除外
除了中提供的信息之外,您还会发现许多Python程序员坚持总是使用def而不是lambda,因此我将尝试解释为什么会这样 基本上可以归结为以下几行: 应该有一种——最好只有一种——显而易见的方法来做到这一点 Guido是Python的创建者,其中引用了以下内容: 为什么要放弃lambda?大多数Python用户不熟悉Lisp或Scheme,因此名称容易混淆;此外,还有一个广泛的误解,即lambda可以做嵌套函数不能做的事情-我仍然记得Laura Creighton的《啊哈-我给她看了之后,她觉得没什么区别!即使有一个更好的名字,我认为将这两个选择并列只需要程序员考虑做出与他们的程序无关的选择;没有选择可以简化思维过程。而且,一旦map、filter和reduce都消失了,就不会有很多地方需要编写非常简短的本地代码 功能;Tkinter回调出现在我的脑海中,但我发现回调通常应该是一些状态承载对象的方法,但玩具程序除外
它们具有相同的行为,但关键区别在于lambda是一个表达式,因此不能包含语句。lambda不一定比函数定义更糟糕,只要它们使用得当。然而,它们通常被用来编写单行函数,因为它们可以,即使这使得代码实际上无法读取。例如,考虑以下内容:
sortfilter = lambda a, b, c: sorted(filter(lambda i: i % 2, (i for i in a if i in b)), key=lambda v: c.get(v, v)))
可以写一行lambda,但这是一个非常糟糕的主意 它们具有相同的行为,但关键区别在于lambda是一个表达式,因此不能包含语句。lambda不一定比函数定义更糟糕,只要它们使用得当。然而,它们通常被用来编写单行函数,因为它们可以,即使这使得代码实际上无法读取。例如,考虑以下内容:
sortfilter = lambda a, b, c: sorted(filter(lambda i: i % 2, (i for i in a if i in b)), key=lambda v: c.get(v, v)))
可以写一行lambda,但这是一个非常糟糕的主意 它们是相同的,请检查已反汇编的python字节码
>>> def sex1 (code):
return {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code]
>>> sex2 = lambda code: {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code]
>>> dis.dis(sex1)
2 0 BUILD_MAP 3
3 LOAD_CONST 1 ('masculino')
6 LOAD_CONST 2 ('m')
9 STORE_MAP
10 LOAD_CONST 3 ('femenino')
13 LOAD_CONST 4 ('f')
16 STORE_MAP
17 LOAD_CONST 5 ('ignorado')
20 LOAD_CONST 6 ('')
23 STORE_MAP
24 LOAD_FAST 0 (code)
27 BINARY_SUBSCR
28 RETURN_VALUE
>>> dis.dis(sex2)
1 0 BUILD_MAP 3
3 LOAD_CONST 1 ('masculino')
6 LOAD_CONST 2 ('m')
9 STORE_MAP
10 LOAD_CONST 3 ('femenino')
13 LOAD_CONST 4 ('f')
16 STORE_MAP
17 LOAD_CONST 5 ('ignorado')
20 LOAD_CONST 6 ('')
23 STORE_MAP
24 LOAD_FAST 0 (code)
27 BINARY_SUBSCR
28 RETURN_VALUE
甚至两者都有相同的类型
>>> type(sex1)
<type 'function'>
>>> type(sex2)
<type 'function'>
它们是相同的,请检查已反汇编的python字节码
>>> def sex1 (code):
return {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code]
>>> sex2 = lambda code: {'m': 'masculino', 'f': 'femenino', '': 'ignorado'} [code]
>>> dis.dis(sex1)
2 0 BUILD_MAP 3
3 LOAD_CONST 1 ('masculino')
6 LOAD_CONST 2 ('m')
9 STORE_MAP
10 LOAD_CONST 3 ('femenino')
13 LOAD_CONST 4 ('f')
16 STORE_MAP
17 LOAD_CONST 5 ('ignorado')
20 LOAD_CONST 6 ('')
23 STORE_MAP
24 LOAD_FAST 0 (code)
27 BINARY_SUBSCR
28 RETURN_VALUE
>>> dis.dis(sex2)
1 0 BUILD_MAP 3
3 LOAD_CONST 1 ('masculino')
6 LOAD_CONST 2 ('m')
9 STORE_MAP
10 LOAD_CONST 3 ('femenino')
13 LOAD_CONST 4 ('f')
16 STORE_MAP
17 LOAD_CONST 5 ('ignorado')
20 LOAD_CONST 6 ('')
23 STORE_MAP
24 LOAD_FAST 0 (code)
27 BINARY_SUBSCR
28 RETURN_VALUE
甚至两者都有相同的类型
>>> type(sex1)
<type 'function'>
>>> type(sex2)
<type 'function'>
它有助于区分事物。如果我定义一个函数,我将从def开始,但是在该函数内部,我通常使用lambda
这与英语写作的概念相同。如果某个报价引用了某个报价,则需要更改嵌套报价的外观。括号也是如此 它有助于区分事物。如果我定义一个函数,我将从def开始,但是在该函数内部,我通常使用lambda
这与英语写作的概念相同。如果某个报价引用了某个报价,则需要更改嵌套报价的外观。括号也是如此 我能想到一个细微的区别:打印性别。_name,sex2。_name。@DSM:这和执行def foo:return 1和def bar:return 1没有多大区别。这两个函数仍然是一样的。因为函数有相同的代码,我完全同意没有函数上的差异,但是有几次我检查了_uname _;,我不能用lambda做这件事。YMMV。我能想到一个细微的区别:打印性别。_uname,sex2。_uname。@DSM:这和执行def foo:return 1和def bar:return 1没有多大区别。这两个函数仍然是一样的。因为函数有相同的代码,我完全同意没有函数上的差异,但是有几次我检查了_uname _;,我不能用lambda做这件事。谢谢你的回答和Guido帖子的链接。非常有趣。我自己也经历过:自从我们从py2.7迁移到py3.2之后,大多数映射、过滤器等表达式都变成了生成器,比如Lif x中x的fx。尽管如此,我很高兴我们仍然得到了lambda。谢谢你的回答和Guido帖子的链接。非常有趣。我自己也经历过:自从我们从py2.7迁移到py3.2之后,大多数映射、过滤器等表达式都变成了生成器,比如Lif x中x的fx。尽管如此,我还是很高兴我们还有兰博达。