filter
, map
y reduce
funcionan perfectamente en Python 2. Aquí hay un ejemplo:
>>> def f(x):
return x % 2 != 0 and x % 3 != 0
>>> filter(f, range(2, 25))
[5, 7, 11, 13, 17, 19, 23]
>>> def cube(x):
return x*x*x
>>> map(cube, range(1, 11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
>>> def add(x,y):
return x+y
>>> reduce(add, range(1, 11))
55
Pero en Python 3, recibo los siguientes resultados:
>>> filter(f, range(2, 25))
<filter object at 0x0000000002C14908>
>>> map(cube, range(1, 11))
<map object at 0x0000000002C82B70>
>>> reduce(add, range(1, 11))
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
reduce(add, range(1, 11))
NameError: name 'reduce' is not defined
Agradecería que alguien me explicara por qué es así.
Captura de pantalla del código para mayor claridad:
python
python-3.x
filter
functional-programming
reduce
Dick Lucas
fuente
fuente
Respuestas:
Puede leer sobre los cambios en What's New In Python 3.0 . Debe leerlo detenidamente cuando pase de 2.xa 3.x ya que se ha cambiado mucho.
La respuesta completa aquí son citas de la documentación.
Vistas e iteradores en lugar de listas
Builtins
fuente
list(map(...)
todas partes ... cómo en el mundo es que la legibilidad ayuda ...python
parece que no puede manejar la aplicación progresiva / de transmisión de combinadores funcionales. En otros idiomas, puedo encadenar una docena de operaciones contra una colección en una fila y es legible. ¿Aquí? ¿Qué quieres, una docena de formas anidadasin
?list
llamada? Pensé que el significado de "transmisión" es "no se crea ninguna lista; procese cada elemento de la entrada completamente antes de pasar al siguiente".map
.La funcionalidad de
map
yfilter
se cambió intencionalmente para devolver iteradores, y reducir se eliminó de ser incorporado y se colocó enfunctools.reduce
.Entonces, para
filter
ymap
, puede envolverloslist()
para ver los resultados como lo hizo antes.La recomendación ahora es que reemplace su uso de mapas y filtros con expresiones de generadores o comprensiones de listas. Ejemplo:
Dicen que los bucles for son un 99 por ciento de las veces más fáciles de leer que reducir, pero simplemente me quedaría con ellos
functools.reduce
.Editar : La cifra del 99 por ciento se extrae directamente de la página Novedades en Python 3.0 creada por Guido van Rossum.
fuente
[i*i*i for i in range(1,11)]
i**3
llamarái.__pow__(3)
yi*i*i
i.__mul__(i).__mul__(i)
(o algo así). Con ints no importa, pero con números numpy / clases personalizadas incluso podría producir resultados diferentes.list(list(list(.. )))
hacer lo que ya era detallado en python.Como una adición a las otras respuestas, esto suena como un buen caso de uso para un administrador de contexto que reasignará los nombres de estas funciones a las que devuelven una lista y la introducen
reduce
en el espacio de nombres global.Una implementación rápida podría verse así:
Con un uso que se ve así:
Que imprime:
Solo mis 2 centavos :-)
fuente
python
como lengua es un desastre - pero tiene v buenos a excelentes bibliotecas:numpy
,pandas
,statsmodels
y amigos .. Me habían BULIDING bibliotecas de conveniencia como usted muestra aquí para reducir el dolor de la lengua nativa - pero han perdido la energía y no tratar de alejarse de adata.frame
/datatable
, oxarray
. Pero felicitaciones por intentar ..Dado que el
reduce
método se ha eliminado de la función integrada de Python3, no olvide importarlofunctools
en su código. Mire el fragmento de código a continuación.fuente
Estos son los ejemplos de filtro, mapa y funciones de reducción.
//Filtrar
//Mapa
//Reducir
La función de reducción, ya que no se usa comúnmente, se eliminó de las funciones integradas en Python 3. Todavía está disponible en el módulo functools, por lo que puede hacer:
fuente
Una de las ventajas de mapear, filtrar y reducir es cuán legibles se vuelven cuando los "encadena" para hacer algo complejo. Sin embargo, la sintaxis incorporada no es legible y está "al revés". Por lo tanto, sugiero usar el
PyFunctional
paquete ( https://pypi.org/project/PyFunctional/ ). Aquí hay una comparación de los dos:Versión PyFunctional
Sintaxis muy legible. Puedes decir:
Versión predeterminada de Python
Todo está al revés. Necesitas decir:
fuente