Python3: ¿La función integrada de "mapa" tiene un error?

Takuo Matsuoka:

La siguiente tuve con Python 3.8.1 (en MacOS Mojave, 10.14.6, así como Python 3.7 (o alguna más) en algunas otras plataformas). Soy nuevo en la computación y no sé cómo solicitar una mejora de un idioma, pero creo que he encontrado un comportamiento extraño de la función incorporada map.

Como el código next(iter(()))aumentos StopIteration, que esperaba obtener StopIterationde la siguiente código:

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

Para mi sorpresa, este silencio volvió la tupla ()!

Por lo que parece el desembalaje del objeto de mapa se detuvo cuando StopIterationllegó a nextgolpear el "vacío" iterador devuelto por iter(()). Sin embargo, no creo que la excepción se maneja bien, como StopIterationno se planteó antes de que el "vacío" iterador fue escogido de la lista (al ser golpeado por next).

  1. ¿He entendido correctamente el comportamiento?
  2. De alguna manera está destinado este comportamiento?
  3. ¿Esto puede cambiar en un futuro cercano? O ¿cómo puedo conseguirlo?

Editar: El comportamiento es similar si desempaquetar el objeto de mapa de diferentes maneras, tales como mediante list, por para-loop, desembalaje dentro de una lista, desembalaje para argumentos de la función, por set, dict. Así que yo creo que no es tuplesino maplo que está mal.

Editar: En realidad, en Python 2 (2.7.10), las "mismas" aumentos de código StopIteration. Creo que esto es el resultado deseable (excepto que mapen este caso no devuelve un iterador).

user2357112 apoya Mónica:

Esto no es un mapfallo de funcionamiento. Es una consecuencia desagradable de la decisión de Python que depender de excepciones para el control de flujo: errores reales parecen flujo normal de control.

Cuando mapllama nexta iter(()), nextaumentos StopIteration. Esto StopIterationse propaga fuera de map.__next__y dentro de la tuplellamada. Este StopIterationse parece a la StopIterationque map.__next__normalmente recaudar para indicar el final de la ruta, por lo que tuplecree que el mapa es simplemente fuera de los elementos.

Esto conduce a consecuencias más raro que lo que viste. Por ejemplo, un mapiterador no marca en sí agota cuando la función asignada genera una excepción, para que pueda mantener la iteración sobre ella incluso después:

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

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

Salida:

()
(1,)

(El CPython mapaplicación no tiene realmente una forma de marcar en sí agotado - que se basa en el iterador subyacente (s) para eso.)

Este tipo de problema StopIteration era lo suficientemente molesto que realmente cambiaron el manejo del generador StopIteration para mitigarlo. StopIteration utiliza para propagar normalmente de un generador, pero ahora, si un StopIteration se propagaría de un generador, es reemplazado con un RuntimeError por lo que no se ve como el generador termina de forma normal. Esto sólo afecta a los generadores, sin embargo, no les gusta otros iteradores map.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=365274&siteId=1
Recomendado
Clasificación