Python中的lambda
我正在重新研究一些用Python写的Scheme练习(如果这样说有意义的话),想了解Python在函数式编程方面能做些什么。我的问题是关于Python中的lambda:我能否在Python中定义一个通用函数,并将一个运算符作为参数之一?
想象一下这个:
def f (op,x,y):
#return some lambda function that combines x and y in the appropriate way
#i.e if op is +, then return x+y, if op is -, then return x-y etc
#Edit : added usage
#this should be called like this:
f(+, 1,2) #should return 3
我知道在Scheme中这是可能的,但在Python中有没有类似的东西?我感觉Python中的lambda只是定义方法的一种更简短的方式,而且我没有找到在Python中定义通用组合函数的方法。
5 个回答
我觉得你最好的办法是写一个函数来执行这个操作,然后把这个函数传进去:
def f(op, x, y):
return op(x, y)
f(lambda x, y: x + y, 1, 2)
不过这样看起来有点多余,因为你可以直接这样做:
f = lambda x, y: x + y
f(1, 2)
在Python中,运算符其实并不是函数,更像是方法。比如说,x + y
其实是 x.__add__(y)
的简写,或者是 y.__radd__(x)
。你可以使用 operator
模块 中的函数来模拟你想要的行为。
我能看到你问题中的一些要点,我们一个一个来讲:
1. 我可以把一个函数当作参数传给别人吗?
可以的:
def f(op, x, y):
return op(x, y)
def add(x, y):
return x + y
f(add, 10, 7) #gives 17
2. 那运算符呢?
跟Scheme不同,Python中的运算符并不是函数,所以你不能直接把它们作为参数传递。你可以自己创建一个包装函数,或者从标准库中导入operator模块。
import operator
operator.add(1, 2)
(lambda x,y : x+y)(1, 2)
运算符不是实际的函数在大多数情况下有点遗憾,但至少Python给我们提供了链式比较,比如10 <= x < 100
,算是个补偿...
3. 那Python和Scheme之间有什么区别呢?
一般来说,Python中的函数和Scheme中的函数一样强大,但有一些需要注意的地方:
lambda关键字的限制
你只能用一个表达式作为函数的主体。
f = lambda x, y: x + y
因为在Python中有很多是语句而不是表达式(比如赋值、2.x的print
等),所以你通常需要退而求其次,使用命名函数。
有闭包
def make_printer(msg):
def printer():
print msg
return printer
printer('a message')()
但是在闭包中修改变量会很麻烦
这样做不行。它试图为内部函数绑定一个新的n,而不是使用外部的那个。
def make_counter(n):
def inc():
n = n + 1
return n
return inc
新的3.x的nonlocal关键字
def make_counter(n):
def inc():
nonlocal n
n = n + 1
return n
return inc
使用可变对象的变通方法
def make_counter(n):
nw = [n]
def inc():
nw[0] = nw[0] + 1
return nw[0]
return inc
用对象代替闭包。使用神奇的__call__
方法来假装它是一个函数。
class Counter:
def __init__(self, n):
self.n = n
def __call__(self):
self.n += 1
return self.n