¿Alguien aquí tiene algún código útil que use la función reduce () en python? ¿Hay algún código que no sea el habitual + y * que vemos en los ejemplos?
Consulte el destino de reduce () en Python 3000 por GvR
¿Alguien aquí tiene algún código útil que use la función reduce () en python? ¿Hay algún código que no sea el habitual + y * que vemos en los ejemplos?
Consulte el destino de reduce () en Python 3000 por GvR
from functools import reduce
permite que el mismo código funcione en Python 2 y 3.Respuestas:
Los otros usos que he encontrado para él además de + y * fueron con y y o, pero ahora tenemos
any
yall
para reemplazar esos casos.foldl
yfoldr
aparecen mucho en Scheme ...Aquí hay algunos usos lindos:
Acoplar una lista
Objetivo: convertirse
[[1, 2, 3], [4, 5], [6, 7, 8]]
en[1, 2, 3, 4, 5, 6, 7, 8]
.Lista de dígitos a un número
Objetivo: convertirse
[1, 2, 3, 4, 5, 6, 7, 8]
en12345678
.Feo, camino lento:
Bonita
reduce
manera:fuente
timeit.repeat('int("".join(map(str, digit_list)))', setup = 'digit_list = list(d%10 for d in xrange(1,1000))', number=1000)
toma ~ 0.09 segundos mientras quetimeit.repeat('reduce(lambda a,d: 10*a+d, digit_list)', setup = 'digit_list = list(d%10 for d in xrange(1,1000))', number=1000)
toma 0.36 segundos (aproximadamente 4 veces más lento). Básicamente, la multiplicación por 10 se vuelve costosa cuando la lista se hace grande, mientras que int to str y la concatenación se mantienen baratas.timeit.repeat('convert_digit_list_to_int(digit_list)', setup = 'digit_list = [d%10 for d in xrange(1,10)]\ndef convert_digit_list_to_int(digits):\n i = 0\n for d in digits:\n i = 10*i + d\n return i', number=100000)
toma 0.06 s,timeit.repeat('reduce(lambda a,d: 10*a+d, digit_list)', setup = 'digit_list = list(d%10 for d in xrange(1,10))', number=100000)
toma 0.12 sy el conversión de dígitos al método str toma 0.16 s.reduce()
se puede usar para encontrar el mínimo común múltiplo de 3 o más números :Ejemplo:
fuente
lcm
en la segunda línea?lcm()
devuelve el mínimo común múltiplo de dos números.reduce()
podría usarse para resolver nombres punteados (donde noeval()
es seguro usarlo):fuente
Encuentre la intersección de N listas dadas:
devoluciones:
vía: Python - Intersección de dos listas
fuente
Creo que reducir es un comando tonto. Por lo tanto:
fuente
El uso de
reduce
eso que encontré en mi código involucró la situación en la que tenía cierta estructura de clase para la expresión lógica y necesitaba convertir una lista de estos objetos de expresión en una conjunción de las expresiones. Ya tenía una funciónmake_and
para crear una conjunción dada dos expresiones, así que escribíreduce(make_and,l)
. (Sabía que la lista no estaba vacía; de lo contrario, habría sido algo asíreduce(make_and,l,make_true)
).Esta es exactamente la razón por la que (a algunos) programadores funcionales les gusta
reduce
(o pliegan funciones, como se suele llamar a tales funciones). A menudo existen ya muchas funciones binarias como+
,*
,min
,max
, concatenación y, en mi caso,make_and
ymake_or
. Tener unreduce
hace que sea trivial levantar estas operaciones a listas (o árboles o lo que sea que tenga, para funciones de plegado en general).Por supuesto, si a
sum
menudo se usan ciertas instancias (como ), entonces no querrá seguir escribiendoreduce
. Sin embargo, en lugar de definirlosum
con algún ciclo for, puede definirlo con la misma facilidadreduce
.La legibilidad, como lo mencionaron otros, es de hecho un problema. Sin embargo, podría argumentar que la única razón por la cual las personas encuentran
reduce
menos "claro" es porque no es una función que mucha gente conoce y / o usa.fuente
and
operador:L and reduce(make_and, L)
si devolver la lista vacía es apropiado en este casoComposición de funciones : si ya tiene una lista de funciones que le gustaría aplicar en sucesión, como:
Luego puede aplicarlos todos consecutivamente con:
En este caso, el encadenamiento de métodos puede ser más legible. Pero a veces no es posible, y este tipo de composición puede ser más fácil de leer y mantener que un
f1(f2(f3(f4(x))))
tipo de sintaxis.fuente
Puedes reemplazar
value = json_obj['a']['b']['c']['d']['e']
con:Si ya tiene la ruta
a/b/c/..
como una lista. Por ejemplo, cambie los valores en dict de dictados anidados utilizando elementos en una lista .fuente
@Blair Conrad: También podría implementar su glob / reduce usando la suma, así:
Esto es menos detallado que cualquiera de sus dos ejemplos, es perfectamente pitónico y sigue siendo solo una línea de código.
Entonces, para responder la pregunta original, personalmente trato de evitar el uso de reducir porque nunca es realmente necesario y encuentro que es menos claro que otros enfoques. Sin embargo, algunas personas se acostumbran a reducir y prefieren enumerar las comprensiones (especialmente los programadores de Haskell). Pero si aún no está pensando en un problema en términos de reducción, probablemente no necesite preocuparse por usarlo.
fuente
sum
yreduce
conducen a un comportamiento cuadrático. Se puede hacer en un tiempo lineal:files = chain.from_iterable(imap(iglob, args))
. Aunque probablemente no importe en este caso debido al tiempo que le toma a glob () acceder a un disco.reduce
se puede usar para admitir búsquedas de atributos encadenados:Por supuesto, esto es equivalente a
pero es útil cuando su código necesita aceptar una lista arbitraria de atributos.
(Los atributos encadenados de longitud arbitraria son comunes cuando se trata de modelos Django).
fuente
reduce
es útil cuando necesita encontrar la unión o intersección de una secuencia deset
objetos similares.(Además de los
set
s reales , un ejemplo de estos son los objetos Q de Django ).Por otro lado, si está tratando con
bool
s, debe usarany
yall
:fuente
Después de ajustar mi código, parece que lo único que he usado para reducir es calcular el factorial:
fuente
Estoy escribiendo una función de composición para un idioma, así que construyo la función compuesta usando reducir junto con mi operador de aplicación.
En pocas palabras, componer toma una lista de funciones para componer en una sola función. Si tengo una operación compleja que se aplica por etapas, quiero poner todo junto de esta manera:
De esta manera, puedo aplicarlo a una expresión así:
Y quiero que sea equivalente a:
Ahora, para construir mis objetos internos, quiero que diga:
(La clase Lambda crea una función definida por el usuario y Apply crea una aplicación de función).
Ahora, reducir, desafortunadamente, se dobla de la manera incorrecta, así que terminé usando, aproximadamente:
Para averiguar qué reducción produce, pruebe estos en REPL:
fuente
compose = lambda *func: lambda arg: reduce(lambda x, f: f(x), reversed(funcs), arg)
para generar todas las posibles combinaciones de las funciones para las pruebas de rendimiento.reducir se puede utilizar para obtener la lista con el enésimo elemento máximo
devolvería [5, 2, 5, 7] ya que es la lista con un tercer elemento máximo +
fuente
Reducir no se limita a operaciones escalares; También se puede utilizar para clasificar cosas en cubos. (Esto es lo que uso reducir para la mayoría de las veces).
Imagine un caso en el que tiene una lista de objetos y desea reorganizarla jerárquicamente en función de las propiedades almacenadas de manera plana en el objeto. En el siguiente ejemplo, produzco una lista de objetos de metadatos relacionados con artículos en un periódico codificado en XML con la
articles
función.articles
genera una lista de elementos XML y luego los mapea uno por uno, produciendo objetos que contienen información interesante sobre ellos. En la parte frontal, voy a querer que el usuario explore los artículos por sección / subsección / título. Así que solíareduce
tomar la lista de artículos y devolver un solo diccionario que refleja la jerarquía de sección / subsección / artículo.Doy ambas funciones aquí porque creo que muestra cómo map y reduce pueden complementarse muy bien cuando se trata de objetos. Lo mismo podría haberse logrado con un bucle for ... pero pasar un tiempo serio con un lenguaje funcional ha tendido a hacerme pensar en términos de mapa y reducir.
Por cierto, si alguien tiene una mejor manera de establecer propiedades como lo estoy haciendo yo
extract
, donde los padres de la propiedad que desea establecer aún no existen, por favor hágamelo saber.fuente
No estoy seguro de si esto es lo que busca, pero puede buscar el código fuente en Google .
Siga el enlace para buscar 'function: reduce () lang: python' en la búsqueda de Google Code
A primera vista, los siguientes proyectos utilizan
reduce()
etc. etc., pero estos no son sorprendentes ya que son grandes proyectos.
La funcionalidad de reducir se puede hacer usando la función de recursión, que supongo que Guido pensó que era más explícita.
Actualizar:
Dado que la búsqueda de código de Google se suspendió el 15 de enero de 2012, además de volver a las búsquedas regulares de Google, hay algo llamado Colección de fragmentos de código que parece prometedor. Varios otros recursos se mencionan en las respuestas a esta pregunta (cerrada) ¿ Reemplazo para Google Code Search? .
Actualización 2 (29 de mayo de 2017):
Una buena fuente para ejemplos de Python (en código de código abierto) es el motor de búsqueda Nullege .
fuente
for
bucle.lang:python "reduce("
encontrará definiciones quereduce
dependerán del estilo de codificación del código fuente.fuente
fuente
Solía
reduce
concatenar una lista de vectores de búsqueda de PostgreSQL con el||
operador en sqlalchemy-searchable:fuente
Tengo una antigua implementación Python de pipegrep que usa reduce y el módulo glob para construir una lista de archivos para procesar:
Lo encontré útil en ese momento, pero realmente no es necesario, ya que algo similar es igual de bueno, y probablemente más legible
fuente
files = [glob.glob(f) for f in args]
itertools
, usando laflatten()
receta de docs.python.org/library/itertools.html , y luego escribiendo:files = flatten(glob.glob(f) for f in args)
(Y esta vez, probé el código antes de publicarlo, y sé que esto funciona correctamente.)files = chain.from_iterable(imap(iglob, args))
wherechain
,imap
are fromitertools
module yglob.iglob
es útil si un patrón deargs
puede generar archivos de varios directorios.Digamos que hay algunos datos estadísticos anuales almacenados en una lista de contadores. Queremos encontrar los valores MIN / MAX en cada mes a través de los diferentes años. Por ejemplo, para enero sería 10. Y para febrero sería 15. Necesitamos almacenar los resultados en un nuevo contador.
fuente
Tengo objetos que representan algún tipo de intervalos superpuestos (exones genómicos) y redefiní su intersección usando
__and__
:Luego, cuando tengo una colección de ellos (por ejemplo, en el mismo gen), uso
fuente
Acabo de encontrar un uso útil de
reduce
: dividir cadenas sin quitar el delimitador . El código es completamente del blog Programatic Speaking. Aquí está el código:Aquí está el resultado:
Tenga en cuenta que maneja casos extremos que la respuesta popular en SO no. Para una explicación más detallada, te estoy redirigiendo a la publicación original del blog.
fuente
Usando reduce () para averiguar si una lista de fechas es consecutiva:
fuente