我想了解如何在python中使用map
,谷歌搜索将我带到了http://www.bogotobogo.com/python/python_fncs_map_filter_reduce.php,我觉得这很有帮助。
该页面上的一个代码使用for循环,并以有趣的方式将map
放入for循环中,map
函数中使用的列表实际上包含2个函数的列表。这是代码:
def square(x):
return (x**2)
def cube(x):
return (x**3)
funcs = [square, cube]
for r in range(5):
value = map(lambda x: x(r), funcs)
print value
输出:
[0, 0]
[1, 1]
[4, 8]
[9, 27]
[16, 64]
因此,在该教程的这一点上,我认为“如果您可以使用函数动态编写代码(lambda),那么可以使用def
”使用标准函数编写代码。所以我把代码更改为:
def square(x):
return (x**2)
def cube(x):
return (x**3)
def test(x):
return x(r)
funcs = [square, cube]
for r in range(5):
value = map(test, funcs)
print value
我得到了与第一段代码相同的输出,但是让我困扰的是变量r
取自全局命名空间,并且代码不是紧密的函数式编程。还有我被绊倒的地方。这是我的代码:
def square(x):
return (x**2)
def cube(x):
return (x**3)
def power(x):
return x(r)
def main():
funcs = [square, cube]
for r in range(5):
value = map(power, funcs)
print value
if __name__ == "__main__":
main()
我玩过这段代码,但问题在于传入函数def power(x)
。我已尝试过多种尝试传递给此函数的方法,但lambda能够自动将x
变量分配给列表funcs
的每个迭代。
有没有办法通过使用标准的def
函数来实现这一点,还是不可能只使用lambda?因为我正在学习python而这是我的第一个语言,我试图了解这里发生了什么。
答案 0 :(得分:4)
您可以将power()
函数嵌套在main()
函数中:
def main():
def power(x):
return x(r)
funcs = [square, cube]
for r in range(5):
value = map(power, funcs)
print value
这样r
现在再次从周围的范围中获取,但不是全局的。相反,它是一个闭包变量。
但是,使用lambda
只是从周围范围注入r
并将其传递到power()
函数的另一种方法:
def power(r, x):
return x(r)
def main():
funcs = [square, cube]
for r in range(5):
value = map(lambda x: power(r, x), funcs)
print value
此处r
仍然是非本地的,取自父作用域!
您可以创建lambda,其中r
是第二个参数的默认值:
def power(r, x):
return x(r)
def main():
funcs = [square, cube]
for r in range(5):
value = map(lambda x, r=r: power(r, x), funcs)
print value
现在r
作为默认值传入,因此它被视为本地。但是出于map()
的目的,这并没有真正发挥作用。
答案 1 :(得分:3)
Currying是另一种选择。因为两个参数的函数与一个参数的函数相同,后者返回另一个接受剩余参数的函数,所以你可以这样写:
def square(x):
return (x**2)
def cube(x):
return (x**3)
def power(r):
return lambda(x): x(r) # This is where we construct our curried function
def main():
funcs = [square, cube]
for y in range(5):
value = map(power(y), funcs) # Here, we apply the first function
# to get at the second function (which
# was constructed with the lambda above).
print value
if __name__ == "__main__":
main()
使关系更加明确,类型为(a, b) -> c
的函数(带有a
类型参数的函数和类型为b
的参数,并返回一个值类型c
)的类型等同于类型a -> (b -> c)
的函数。
如果你想深入了解这种等价背后的数学,你可以使用一些代数来看待这种关系。将这些类型视为代数数据类型,我们可以将任何函数a -> b
转换为b a ,将任何对(a, b)
转换为a * b。有时函数类型称为“指数”,并且由于此连接,对类型称为“产品类型”。从这里,我们可以看到
c (a * b) =(c b ) a
等等,
(a, b) -> c ~= a -> (b -> c)
答案 2 :(得分:1)
为什么不简单地将函数作为参数的一部分传递给power()
,并使用itertools.product
创建所需的(value, func)
组合?
from itertools import product
# ...
def power((value, func)):
return func(value)
for r in range(5):
values = map(power, product([r], funcs))
print values
或者,如果您不希望/要求按功能对结果进行分组,而是想要一个平面列表,您可以这样做:
values = map(power, product(range(5), funcs))
print values
注意:签名power((value, func))
定义power()
以接受单个2元组参数,该参数会自动解压缩到value
和func
。
相当于
def power(arg):
value, func = arg