python - 在 Python 3 map() 中使用多个函数
问题描述
我不确定为什么下面的代码有效。根据文档,map 仅将一个函数作为第一个参数并将其应用于一个或多个可迭代对象,具体取决于函数采用多少参数。
map(function, iterable..)
但是,代替可迭代对象,您可以传递多个函数,并且以某种方式将它们视为可迭代对象。不知何故,这条线正在使用函数 add、square 和 str 并将它们视为可迭代对象。
如何将函数视为有效的可迭代对象?
def add(x):
return x + x
def square(x):
return x * x
nums = [1, 2, 3, 4, 5]
for i in nums:
vals = list(map(lambda x: x(i), (add, square, str)))
print(vals)
返回:
[2, 1, '1']
[4, 4, '2']
[6, 9, '3']
[8, 16, '4']
[10, 25, '5']
*EDIT Martijn 回答了这个问题。这段代码做同样的事情,但把它从 lambda 函数中分离出来,显示add, square, str
函数是如何被迭代的。
def add(x):
return x + x
def square(x):
return x * x
def act_on_iter(iter_obj, i):
return iter_obj(i)
nums = [1, 2, 3, 4, 5]
for i in nums:
vals = list(map(act_on_iter, (add, square, str), [i] * 3))
print(vals)
返回相同
[2, 1, '1']
[4, 4, '2']
[6, 9, '3']
[8, 16, '4']
[10, 25, '5']
解决方案
您正在传递一个可迭代的可调用对象:
(add, square, str)
那是一个元组,元组是可迭代的。可迭代对象中的内容无关紧要,在 Python 中,函数是一等对象,就像字符串和整数以及类和实例一样。您可以传递函数,包括将它们存储在元组中。
然后你有一个lambda
可调用的:
lambda x: x(i)
它获取迭代中的每个项目并将它们也视为可调用对象。x
设置为add
,然后到square
,然后到str
,并且lambda
调用每个传入i
。同样,函数只是另一种类型的对象,您可以将一个函数作为参数值传递给另一个函数,这里接收函数对象的参数名为x
。然后,表达式x(i)
调用分配给 的任何内容x
。
如果您将 替换为lambda
(print
没有()
括号,我们引用的是函数对象),那么您会看到:
>>> list(map(print, (add, square, str)))
<function add at 0x11645a670>
<function square at 0x11645a790>
<class 'str'>
[None, None, None]
该[None, None, None]
列表是调用print()
3 次的结果,该函数始终返回None
. 有趣的部分是 之前的输出[None, None, None]
,它们是元组中三个函数中每一个的字符串表示(add, square, str)
。
在您的示例代码中,您有一个for
循环nums
,将每个值分配给i
, so 1
, 2
,3
等。所以您看到的实际输出是通过map()
重复使用产生的,作为i
更改:
i = 1
, ->[add(1), square(1), str(1)]
->[2, 1, '1']
i = 2
, ->[add(2), square(2), str(2)]
->[4, 4, '2']
i = 3
, ->[add(3), square(3), str(3)]
->[6, 9, '3']
i = 4
, ->[add(4), square(4), str(4)]
->[8, 16, '4']
i = 5
, ->[add(5), square(5), str(5)]
->[10, 25, '5']
推荐阅读
- c# - 如何在数据网格中使用更新面板
- gradle - 在 OSGi fat jar bundle 中查找重复的 JAR
- visual-studio-code - C++ vscode 扩展使操作系统极其缓慢
- c# - Dot Net 中的 XML 和 XAML 有什么区别?
- json - 面临将数据从 JSON 对象绑定到的问题
- c++ - 具有多个 OR 条件的 while 循环不退出循环
- crystal-reports - 水晶报表 - 无法过滤自定义公式编号字段
- gnu-make - 使用 make -j 时如何识别失败的命令
- ansible - 包括来自不同文件的处理程序
- php - 如何检查输入值是否以大写/开头或是否有小写/或在PHP中是否全部大写?