Ouvi dizer que lambdas multilinhas não podem ser adicionadas no Python porque elas colidiriam sintaticamente com outras construções de sintaxe no Python. Eu estava pensando sobre isso no ônibus hoje e percebi que não conseguia pensar em uma única construção Python com a qual as lambdas multilinhas se chocassem. Dado que conheço bem o idioma, isso me surpreendeu.
Agora, tenho certeza de que Guido tinha um motivo para não incluir lambdas multilinhas no idioma, mas por curiosidade: qual é a situação em que incluir uma lambda multilinha seria ambíguo? É o que eu ouvi falar verdade, ou há algum outro motivo pelo qual o Python não permite lambdas multilinhas?
lambda
expressões em primeiro lugar; você pode simplesmente usardef
instruções em expressões.Respostas:
Veja o seguinte:
É um retorno lambda
(y, [1,2,3])
(assim, o mapa obtém apenas um parâmetro, resultando em um erro)? Ou voltay
? Ou é um erro de sintaxe, porque a vírgula na nova linha está incorreta? Como Python saberia o que você quer?Dentro da parênteses, a indentação não importa para python, então você não pode trabalhar sem ambiguidade com multilinhas.
Este é apenas um exemplo simples, provavelmente há mais exemplos.
fonte
Guido van Rossum (o inventor do Python) responde a essa pergunta exata em um antigo post de blog .
Basicamente, ele admite que é teoricamente possível, mas que qualquer solução proposta seria não-pitonica:
fonte
Isso geralmente é muito feio (mas às vezes as alternativas são ainda mais feias), portanto, uma solução alternativa é fazer uma expressão entre chaves:
Porém, ele não aceita nenhuma atribuição, portanto, você deverá preparar os dados com antecedência. O local que achei útil é o wrapper PySide, onde às vezes você tem retornos curtos. Escrever funções-membro adicionais seria ainda mais feio. Normalmente você não precisará disso.
Exemplo:
fonte
lambda arg
esetattr(arg, 'attr','value')
subverter "sem atribuições ...". E depois há avaliação de curto-circuitoand
eor
... é o Javascript que faz isso. Afunda raízes em você, como hera em uma parede. Eu quase espero esquecer isso no Natal.PEP
diretrizes)Alguns links relevantes:
Por um tempo, eu estava acompanhando o desenvolvimento do Reia, que inicialmente teria a sintaxe baseada em indentação do Python com blocos Ruby também, tudo sobre Erlang. Mas, o designer acabou desistindo da sensibilidade do recuo, e este post que ele escreveu sobre essa decisão inclui uma discussão sobre problemas com os quais ele se deparou com recuo + blocos de várias linhas e uma apreciação maior que ele ganhou pelas questões / decisões de design de Guido:
http://www.unlimitednovelty.com/2009/03/indentation-sensitivity-post-mortem.html
Além disso, aqui está uma proposta interessante para os blocos de estilo Ruby no Python que encontrei em Guido, onde uma resposta foi lançada sem realmente derrubá-la (não tenho certeza se houve alguma derrubada subsequente):
http://tav.espians.com/ruby-style-blocks-in-python.html
fonte
[Editar] Leia esta resposta. Explica por que lambda multilinha não é uma coisa.
Simplificando, é atípico. Da publicação de blog de Guido van Rossum:
fonte
Deixe-me apresentar um corte glorioso, mas aterrador:
Agora você pode usar este
LET
formulário da seguinte forma:que dá:
[0, 3, 8]
fonte
Sou culpado de praticar esse truque sujo em alguns dos meus projetos, que é um pouco mais simples:
Espero que você consiga encontrar uma maneira de se manter pythonic, mas se você tiver que fazer isso menos doloroso do que usar exec e manipular globals.
fonte
Deixe-me tentar resolver o problema de análise do @balpha. Eu usaria parênteses ao redor da lamda multilinha. Se não houver parênteses, a definição lambda é gananciosa. Então a lambda em
retorna uma função que retorna
(y*z, [1,2,3])
Mas
significa
onde func é a lambda multilinha que retorna y * z. Isso funciona?
fonte
map(func, [1,2,3])
e o inferior deve ser um erro porque a função de mapa não possui argumentos suficientes. Também há alguns parênteses extras no código.(Para quem ainda estiver interessado no tópico.)
Considere isso (inclui o uso uniforme dos valores de retorno das declarações em outras declarações dentro da lambda "multilinha", embora seja feio a ponto de vomitar ;-)
fonte
state.clear()
porque os argumentos padrão são criados apenas uma vez quando a função é criada.Você pode simplesmente usar slash (
\
) se tiver várias linhas para sua função lambdaExemplo:
fonte
Estou começando com python, mas vindo do Javascript, a maneira mais óbvia é extrair a expressão como uma função ....
Exemplo artificial, a expressão multiplicar
(x*2)
é extraída como função e, portanto, eu posso usar várias linhas:https://repl.it/@datracka/python-lambda-function
Talvez não responda exatamente à pergunta se foi assim que fazer multilinha na própria expressão lambda , mas caso alguém obtenha esse encadeamento procurando depurar a expressão (como eu), acho que ajudará
fonte
map(multiply, [1, 2, 3])
?No assunto de hacks feios, você sempre pode usar uma combinação de
exec
e uma função regular para definir uma função de múltiplas linhas como esta:Você pode agrupar isso em uma função como:
fonte
Eu estava apenas brincando um pouco para tentar entender o ditado com o reduzir e criar esse truque de liner:
Eu estava apenas tentando fazer o mesmo que foi feito nesta compreensão de dict Javascript: https://stackoverflow.com/a/11068265
fonte
Aqui está uma implementação mais interessante de lambdas de várias linhas. Não é possível obter isso devido ao modo como o python usa recuos como uma maneira de estruturar o código.
Felizmente, para nós, a formatação de recuo pode ser desativada usando matrizes e parênteses.
Como alguns já apontaram, você pode escrever seu código assim:
Em teoria, se você tiver uma avaliação da esquerda para a direita, isso funcionaria, mas você ainda perde valores sendo transmitidos de uma expressão para outra.
Uma maneira de conseguir o que é um pouco mais detalhado é ter
Onde cada lambda recebe argumentos do anterior.
Este método permite que você escreva algo que seja um pouco lisp / esquema.
Então você pode escrever coisas assim:
Um método mais complexo pode ser usado para calcular a hipotenusa
Isso retornará uma lista de números escalares para que possa ser usado para reduzir vários valores para um.
Ter tantos lambda certamente não será muito eficiente, mas se você estiver com restrições, pode ser uma boa maneira de fazer algo rapidamente, depois reescreva-o como uma função real posteriormente.
fonte
porque uma função lambda deve ter uma linha, pois é a forma mais simples de uma função,
an entrance, then return
fonte