Alguém aqui tem algum código útil que usa a função reduzir () em python? Existe algum código que não seja o habitual + e * que vemos nos exemplos?
Consulte Destino da redução () no Python 3000 por GvR
Alguém aqui tem algum código útil que usa a função reduzir () em python? Existe algum código que não seja o habitual + e * que vemos nos exemplos?
Consulte Destino da redução () no Python 3000 por GvR
from functools import reduce
permite que o mesmo código para trabalhar em ambos Python 2 e 3.Respostas:
Os outros usos que encontrei além de + e * foram com e e ou, mas agora temos
any
eall
substituímos esses casos.foldl
efoldr
aparecem muito no Scheme ...Aqui estão alguns usos fofos:
Achatar uma lista
Objetivo: transformar
[[1, 2, 3], [4, 5], [6, 7, 8]]
em[1, 2, 3, 4, 5, 6, 7, 8]
.Lista de dígitos para um número
Objetivo: transformar
[1, 2, 3, 4, 5, 6, 7, 8]
em12345678
.Caminho feio e lento:
Maneira bonita
reduce
:fonte
timeit.repeat('int("".join(map(str, digit_list)))', setup = 'digit_list = list(d%10 for d in xrange(1,1000))', number=1000)
leva ~ 0,09 segundos enquantotimeit.repeat('reduce(lambda a,d: 10*a+d, digit_list)', setup = 'digit_list = list(d%10 for d in xrange(1,1000))', number=1000)
leva 0,36 segundos (cerca de 4 vezes mais lento). Basicamente, a multiplicação por 10 se torna cara quando a lista fica grande, enquanto int str e concatenação permanecem 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)
leva 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)
leva 0,12 s e a conversão de dígitos para o método str leva 0,16 s.reduce()
pode ser usado para encontrar o mínimo múltiplo comum para 3 ou mais números :Exemplo:
fonte
lcm
na segunda linha?lcm()
retorna múltiplo menos comum de dois números.reduce()
pode ser usado para resolver nomes pontilhados (ondeeval()
é inseguro demais para usar):fonte
Encontre a interseção de N listas dadas:
retorna:
via: Python - Interseção de duas listas
fonte
Eu acho que reduzir é um comando bobo. Conseqüentemente:
fonte
O uso
reduce
que encontrei no meu código envolveu a situação em que eu tinha alguma estrutura de classe para expressão lógica e precisava converter uma lista desses objetos de expressão em uma conjunção das expressões. Eu já tinha a funçãomake_and
de criar uma conjunção com duas expressões, então escrevireduce(make_and,l)
. (Eu sabia que a lista não estava vazia; caso contrário, teria sido algo parecidoreduce(make_and,l,make_true)
.)Essa é exatamente a razão pela qual (alguns) programadores funcionais gostam
reduce
(ou dobram funções, como normalmente são chamadas). Muitas vezes há já muitas funções binárias como+
,*
,min
,max
, concatenação e, no meu caso,make_and
emake_or
. Tendo umareduce
torna trivial elevar essas operações para listas (ou árvores ou o que você tiver, para funções de dobra em geral).Obviamente, se certas instanciações (como
sum
) são frequentemente usadas, você não deseja continuar escrevendoreduce
. No entanto, em vez de definir osum
loop for some, você pode defini-lo com a mesma facilidadereduce
.Legibilidade, como mencionado por outros, é realmente um problema. Você poderia argumentar, no entanto, que a única razão pela qual as pessoas acham
reduce
menos "claras" é porque não é uma função que muitas pessoas conheçam e / ou usem.fonte
and
operador:L and reduce(make_and, L)
se retornar a lista vazia for apropriado neste casoComposição da função : se você já possui uma lista de funções que deseja aplicar em sucessão, como:
Em seguida, você pode aplicá-los todos consecutivamente com:
Nesse caso, o encadeamento de métodos pode ser mais legível. Mas às vezes isso não é possível, e esse tipo de composição pode ser mais legível e sustentável do que um
f1(f2(f3(f4(x))))
tipo de sintaxe.fonte
Você pode substituir
value = json_obj['a']['b']['c']['d']['e']
por:Se você já possui o caminho
a/b/c/..
como uma lista. Por exemplo, altere valores no dict de dested aninhados usando itens em uma lista .fonte
@Blair Conrad: Você também pode implementar seu glob / reduzir usando sum, assim:
Isso é menos detalhado do que qualquer um dos dois exemplos, é perfeitamente pitônico e ainda é apenas uma linha de código.
Então, para responder à pergunta original, eu pessoalmente tento evitar o uso de reduzir porque isso nunca é realmente necessário e acho que é menos claro do que outras abordagens. No entanto, algumas pessoas se acostumam a reduzir e preferem listar compreensões (especialmente programadores Haskell). Mas se você ainda não está pensando em um problema em termos de redução, provavelmente não precisa se preocupar em usá-lo.
fonte
sum
ereduce
levam ao comportamento quadrático. Isso pode ser feito em tempo linear:files = chain.from_iterable(imap(iglob, args))
. Embora provavelmente não importe nesse caso, devido ao tempo que leva para a glob () acessar um disco.reduce
pode ser usado para suportar pesquisas de atributos encadeados:Claro, isso é equivalente a
mas é útil quando seu código precisa aceitar uma lista arbitrária de atributos.
(Atributos encadeados de comprimento arbitrário são comuns ao lidar com modelos do Django.)
fonte
reduce
é útil quando você precisa encontrar a união ou interseção de uma sequência deset
objetos semelhantes.(Além dos
set
s reais , um exemplo desses são os objetos Q do Django .)Por outro lado, se você está lidando com
bool
s, deve usarany
eall
:fonte
Após grepping meu código, parece que a única coisa que usei reduzi é calcular o fatorial:
fonte
Como estou escrevendo uma função de composição para um idioma, construo a função composta usando reduzir junto com meu operador de aplicação.
Em poucas palavras, escrever compõe uma lista de funções para compor em uma única função. Se eu tiver uma operação complexa aplicada em etapas, quero reunir tudo da seguinte maneira:
Dessa forma, posso aplicá-lo a uma expressão assim:
E eu quero que seja equivalente a:
Agora, para construir meus objetos internos, quero que ele diga:
(A classe Lambda cria uma função definida pelo usuário e o Apply cria um aplicativo de função.)
Agora, infelizmente, reduza dobras da maneira errada, então acabei usando, aproximadamente:
Para descobrir o que reduz produz, tente estes no REPL:
fonte
compose = lambda *func: lambda arg: reduce(lambda x, f: f(x), reversed(funcs), arg)
para gerar todas as combinações possíveis de funções para teste de desempenho.reduzir pode ser usado para obter a lista com o enésimo elemento máximo
retornaria [5, 2, 5, 7], pois é a lista com o máximo do terceiro elemento +
fonte
Reduzir não se limita a operações escalares; também pode ser usado para classificar as coisas em baldes. (Isto é o que eu uso reduzir com mais frequência).
Imagine um caso em que você tenha uma lista de objetos e deseje reorganizá-la hierarquicamente com base nas propriedades armazenadas de maneira simples no objeto. No exemplo a seguir, produzo uma lista de objetos de metadados relacionados a artigos em um jornal codificado em XML com a
articles
funçãoarticles
gera uma lista de elementos XML e os mapeia um a um, produzindo objetos que contêm informações interessantes sobre eles. No front-end, quero permitir que o usuário navegue nos artigos por seção / subseção / título. Então, eu usoreduce
a lista de artigos e retorno um único dicionário que reflete a hierarquia da seção / subseção / artigo.Dou as duas funções aqui porque acho que mostra como mapear e reduzir podem se complementar muito bem ao lidar com objetos. O mesmo poderia ter sido realizado com um loop for ... mas passar algum tempo sério com uma linguagem funcional tende a me fazer pensar em termos de mapa e redução.
A propósito, se alguém tiver uma maneira melhor de definir propriedades como eu
extract
, em que os pais da propriedade que você deseja definir ainda não existem, informe-me.fonte
Não tenho certeza se é isso que você procura, mas você pode pesquisar o código-fonte no Google .
Siga o link para uma pesquisa sobre 'function: reduzir () lang: python' na pesquisa de código do Google
À primeira vista, os seguintes projetos usam
reduce()
etc. etc., mas não são de surpreender, pois são grandes projetos.
A funcionalidade de redução pode ser feita usando a recursão da função, que eu acho que Guido achou mais explícita.
Atualizar:
Como a Pesquisa de código do Google foi descontinuada em 15 de janeiro de 2012, além de reverter para pesquisas regulares do Google, existe algo chamado Coleção de trechos de código que parece promissor. Vários outros recursos são mencionados nas respostas a esta pergunta (fechada) Substituição da Pesquisa de código do Google? .
Atualização 2 (29 de maio de 2017):
Uma boa fonte para exemplos de Python (em código de código aberto) é o mecanismo de pesquisa Nullege .
fonte
for
loop.lang:python "reduce("
encontrará definições dereduce
dependendo do estilo de codificação do código fonte.fonte
fonte
Eu costumava
reduce
concatenar uma lista de vetores de pesquisa do PostgreSQL com o||
operador em sqlalchemy-searchable:fonte
Eu tenho uma implementação Python antiga do pipegrep que usa o reduzir e o módulo glob para criar uma lista de arquivos para processar:
Achei útil na época, mas não é realmente necessário, pois algo semelhante é igualmente bom e provavelmente mais legível
fonte
files = [glob.glob(f) for f in args]
itertools
, usando aflatten()
receita de docs.python.org/library/itertools.html e depois escrevendo:files = flatten(glob.glob(f) for f in args)
(E desta vez, testei o código antes de publicá-lo e sei que isso funciona corretamente.)files = chain.from_iterable(imap(iglob, args))
wherechain
,imap
são doitertools
módulo eglob.iglob
é útil se um padrão deargs
pode gerar arquivos de vários diretórios.Digamos que existem alguns dados estatísticos anuais armazenados em uma lista de contadores. Queremos encontrar os valores MIN / MAX em cada mês nos diferentes anos. Por exemplo, em janeiro, seriam 10. E, em fevereiro, seriam 15. Precisamos armazenar os resultados em um novo contador.
fonte
Eu tenho objetos representando algum tipo de intervalo sobreposto (exons genômicos) e redefinimos sua interseção usando
__and__
:Então, quando eu tenho uma coleção deles (por exemplo, no mesmo gene), eu uso
fonte
Acabei de encontrar um uso útil de
reduce
: split string sem remover o delimitador . O código é inteiramente do blog Programatically Speaking. Aqui está o código:Aqui está o resultado:
Observe que ele lida com casos extremos que a resposta popular no SO não. Para uma explicação mais aprofundada, estou redirecionando você para a postagem original do blog.
fonte
Usando o reduza () para descobrir se uma lista de datas é consecutiva:
fonte