首页 > 解决方案 > Python3: Does the built-in function "map" have a bug?

问题描述

The following I had with Python 3.8.1 (on macOS Mojave, 10.14.6, as well as Python 3.7 (or some older) on some other platforms). I'm new to computing and don't know how to request an improvement of a language, but I think I've found a strange behaviour of the built-in function map.

As the code next(iter(())) raises StopIteration, I expected to get StopIteration from the following code:

tuple(map(next, [iter(())]))

To my surprise, this silently returned the tuple ()!

So it appears the unpacking of the map object stopped when StopIteration came from next hitting the "empty" iterator returned by iter(()). However, I don't think the exception was handled right, as StopIteration was not raised before the "empty" iterator was picked from the list (to be hit by next).

  1. Did I understand the behaviour correctly?
  2. Is this behaviour somehow intended?
  3. Will this be changed in a near future? Or how can I get it?

Edit: The behaviour is similar if I unpack the map object in different ways, such as by list, for for-loop, unpacking within a list, unpacking for function arguments, by set, dict. So I believe it's not tuple but map that's wrong.

Edit: Actually, in Python 2 (2.7.10), the "same" code raises StopIteration. I think this is the desirable result (except that map in this case does not return an iterator).

标签: pythonpython-3.xbehaviorbuilt-inmap-function

解决方案


这不是map错误。这是 Python 决定依赖异常来控制流的一个丑陋的结果:实际错误看起来像正常的控制流。

map呼叫nextiter(())next加注StopIteration。这StopIteration传播出map.__next__和进入tuple呼叫。这StopIteration看起来像StopIteration通常map.__next__会引发地图结束的信号,因此tuple认为地图只是没有元素。

这会导致比你看到的更奇怪的后果。例如,map当映射函数引发异常时,迭代器不会将自身标记为耗尽,因此您甚至可以在之后继续迭代它:

m = map(next, [iter([]), iter([1])])

print(tuple(m))
print(tuple(m))

输出:

()
(1,)

(CPythonmap实现实际上并没有办法将自己标记为耗尽 - 它依赖于底层迭代器。)

这种 StopIteration 问题很烦人,以至于他们实际上改变了生成器的 StopIteration 处理来缓解它。StopIteration 过去通常从生成器传播出去,但是现在,如果 StopIteration 会从生成器传播出去,它会被 RuntimeError 替换,因此它看起来不像生成器正常结束。不过,这只影响生成器,不会影响其他迭代器,例如map.


推荐阅读