映射不同长度的迭代器
Posted
技术标签:
【中文标题】映射不同长度的迭代器【英文标题】:Map on iterators of different length 【发布时间】:2012-11-12 17:16:45 【问题描述】:我在回答 this question 时遇到了以下问题:
>>> from operator import add
>>> map(add,[1,2,3],[1,2])
Traceback (most recent call last):
File "<pyshell#47>", line 1, in <module>
map(add,[1,2,3],[1,2])
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
我希望map
在参数中提供的最小迭代器被消耗后立即停止。
我找到了解决办法:
>>> from itertools import imap
>>> list(imap(add,[1,2,3],[1,2]))
[2, 4]
但是,这是为什么呢?他们的行为不应该是一致的吗?
这是我解决问题的最佳方法吗?
【问题讨论】:
失败的不是 map,而是add()
函数。 add()
要求您可以添加两种类型,您不能将NoneType
添加到int
。您可以定义自己的函数来处理None
,并且 map 可以很好地处理不同长度的列表。
@Matt 我希望它在 smallest 迭代器被消耗后立即停止。
这是可以接受的,你可以想要那个。但我指的是你在问题中提到map fails when the lists of arguments are of different lengths
的地方,这是不正确的。 map()
适用于不同长度的列表,错误是由 add()
函数引起的。
@Matt 我还提供了我所面临的真正问题的链接(从中你可以看到我的不满)。另外,我问了几个问题,其中一个是问map
和imap
的行为是否应该一致。我试图举出一个简短的失败示例,首先想到的是使用add
。我无法预见,您会将不当行为归咎于 add
不接受 None
。因此,我更新了问题并明确表示我希望 map
在消耗完最小的迭代器后立即停止。
是的,我知道你想做什么。我不回答你的问题,已经有一个很好的答案。我只是指出您问题中的措辞不完全正确的地方。在您的示例中有一个例外。 add()
函数引发了该异常。我将您的“地图失败时...”解释为引用该异常,因为这是我看到的唯一“失败”。我的评论是关于你错误地将这个异常归因于map()
,而实际上它是由add()
提出的。 map()
不是“失败”,它正在做它应该做的事情。
【参考方案1】:
如itertools.imap
描述中所述:
创建一个迭代器,使用来自每个可迭代对象的参数计算函数。如果 function 设置为 None,则 imap() 将参数作为元组返回。 与 map() 类似,但在最短的可迭代对象用尽时停止,而不是为较短的可迭代对象填充 None。差异的原因是无限迭代器参数通常是 map() 的错误(因为输出已被完全评估),但代表了向 imap() 提供参数的一种常见且有用的方式。
【讨论】:
我明白了。他们甚至反映在文档中!!! (我会在 10 分钟内接受这个答案,届时 SO 会允许)。 也许您可以尝试回答最后一个问题? 如果你想要两个列表中最短的,那么是的,使用imap
是完全合理的。【参考方案2】:
怎么样:map(sum, zip([1,2,3],[4,5]))
?
【讨论】:
我觉得这样更好,因为它不需要导入imap
。以上是关于映射不同长度的迭代器的主要内容,如果未能解决你的问题,请参考以下文章