¿El objeto de filtro se vacía después de la iteración?

Estoy aprendiendo a usar la función de filter .

Este es el código que he escrito:

 people = [{'name': 'Mary', 'height': 160}, {'name': 'Isla', 'height': 80}, {'name': 'Sam'}] people2 = filter(lambda x: "height" in x, people) 

Como puede ver, lo que estoy tratando de hacer es eliminar todos los diccionarios que no contienen la clave 'height' .

El código funciona correctamente, de hecho si lo hago:

 print(list(people2)) 

Yo obtengo:

 [{'name': 'Mary', 'height': 160}, {'name': 'Isla', 'height': 80}] 

El problema es que si lo hago dos veces:

 print(list(people2)) print(list(people2)) 

La segunda vez, me sale una lista vacía.

¿Me puedes explicar por qué?

Related of "¿El objeto de filtro se vacía después de la iteración?"

Este es un clásico de Python3 Doh !.

Un filtro es un objeto iterable especial sobre el que se puede iterar. Sin embargo, al igual que un generador, puede iterar sobre él solo una vez. Entonces, al llamar a la list(people2) , estás iterando sobre cada elemento del objeto de filter para generar la list . En este punto, ha llegado al final de la iterable y nada más para volver.

Entonces, cuando vuelves a llamar a la list(people2) , obtienes una lista vacía.

Manifestación:

 >>> l = range(10) >>> k = filter(lambda x: x > 5, l) >>> list(k) [6, 7, 8, 9] >>> list(k) [] 

Debo mencionar que con python2, el filter devuelve una lista, por lo que no se encuentra con este problema. El problema surge cuando traes la evaluación perezosa de py3 a la imagen.

Es porque el filtro que realmente gira es un iterador . Este iterador realmente no hace nada hasta que empiezas a usar sus resultados, en este caso cuando lo colocas en una lista. people2 es esta cosa que está lista para filtrar la lista de personas, luego, cuando se llama a la lista, itera a través de la lista de personas y entrega el resultado filtrado. Ahora que el iterador está listo, no queda nada por lo que iterar, por lo que cuando llama a la lista por segunda vez, no hay nada allí.

Lea esto para obtener más detalles: Python perezoso evaluación