部分函数与 lambda 的映射列表

16 投票
3 回答
3759 浏览
提问于 2025-04-16 13:18

我在想,对于大多数例子来说,使用lambda函数还是partial函数,哪个更符合“Python风格”?

比如,我可能想对某个列表使用imap,像是给每个元素加3,可以这样写:

imap(lambda x : x + 3, my_list)

或者使用partial

imap(partial(operator.add, 3), my_list)

我知道在这个例子中,用循环可能会更简单,但我在想一些更复杂的例子。

在Haskell中,我会很容易选择部分应用,但我对Python不太确定。对我来说,lambda函数似乎是更好的选择,但我不知道大多数Python程序员的普遍选择是什么。

3 个回答

4

在编程中,使用lambda表达式的情况确实比其他方式多很多。除非你是在学术环境下做函数式编程,否则最好不要使用functools这个库。

这样做是符合Python风格的。你不需要任何额外的库,甚至连内置的功能都不需要,只要用一个简单的生成器表达式就可以了。

( x + 3 for x in my_list )

这个代码创建了一个生成器,和imap很像。如果你最终还是要把它变成一个列表,那不如直接用列表推导式来做:

[ x + 3 for x in my_list ]
5

在这个例子中,使用lambda函数看起来最合适,而且也更容易理解。

我从来没有在实际应用中见过部分函数的用法。

17

要真正和 imap 一样,可以使用生成器表达式:

(x + 3 for x in mylist)

imap 一样,这个方法不会立刻创建一个新的完整列表,而是根据需要计算结果序列中的元素(因此如果你把结果再用在其他循环中,这种方法比列表推导式要高效得多)。

如果你想知道在实际应用中,partiallambda 更合适的情况,通常是在处理可变数量的参数时:

>>> from functools import partial
>>> def a(*args):
...     return sum(args)
... 
>>> b = partial(a, 2, 3)
>>> b(6, 7, 8)
26

lambda 写的等效版本是...

>>> b = lambda *args: a(2, 3, *args)
>>> b(6, 7, 8)
26

这个写法稍微不那么简洁——不过 lambda 让你可以选择参数的顺序,而 partial 就做不到这一点:

>>> def a(x, y, z):
...    return x + y - z
...
>>> b = lambda m, n: a(m, 1, n)
>>> b(2, 5)
-2

撰写回答