映射不同长度的迭代器

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 我还提供了我所面临的真正问题的链接(从中你可以看到我的不满)。另外,我问了几个问题,其中一个是问mapimap 的行为是否应该一致。我试图举出一个简短的失败示例,首先想到的是使用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

以上是关于映射不同长度的迭代器的主要内容,如果未能解决你的问题,请参考以下文章

由引用传递的迭代器集/映射迭代器不可取消引用

用于组合异步迭代器的映射、过滤器和迭代工具

迭代器模式c++实现

迭代器模式c++实现

迭代器模式c++实现

Map集合遍历的2种方法