Esta é uma pergunta de dicas para jogar golfe em Python.
No golfe em Python, é comum que um envio seja uma função definida como um lambda. Por exemplo,
f=lambda x:0**x or x*f(x-1)
calcula o fatorial de x.
O formato lambda tem duas grandes vantagens :
- O boilerplate de
f=lambda x:...
oulambda x:...
é mais curto que odef f(x):...return...
oux=input()...print...
- Uma chamada recursiva pode ser usada para fazer um loop com pouca sobrecarga de bytes.
No entanto, as lambdas têm a grande desvantagem de permitir apenas uma única expressão, sem instruções. Em particular, isso significa que não há tarefas como c=chr(x+65)
. Isso é problemático quando se tem uma expressão longa cujo valor precisa ser referenciado duas vezes (ou mais).
Atribuições como E=enumerate
são possíveis fora da função ou como argumento opcional, mas somente se elas não dependerem das entradas da função. Argumentos opcionais como f=lambda n,k=min(n,0):...
falha porque a entrada n
não foi definida quando k
é avaliada no momento da definição.
O resultado é que, às vezes, você aspira repetir uma expressão longa em uma lambda porque a alternativa é uma longa não lambda.
lambda s:s.strip()+s.strip()[::-1]
def f(s):t=s.strip();print t+t[::-1]
O ponto de equilíbrio é de cerca de 11 caracteres ( detalhes ), após o qual você alterna para um def
ou program
. Compare isso com o ponto de equilíbrio usual de comprimento 5 para uma expressão repetida:
range(a)+range(b)
r=range;r(a)+r(b)
print s[1:],s[1:]*2
r=s[1:];print r,r*2
Outros idiomas têm soluções alternativas, oitava por exemplo . Existem truques conhecidos para o Python, mas eles são longos, desajeitados e / ou de uso limitado. Um método curto e de uso geral para simular a atribuição em um lambda revolucionaria o golfe em Python.
Quais são as maneiras de um jogador de golfe Python superar ou contornar essa limitação? Que idéias potenciais eles devem ter em mente quando vêem uma expressão longa repetida duas vezes em uma lambda?
Meu objetivo com esta pergunta de dicas é mergulhar profundamente nesse problema e:
- Catalogue e analise soluções alternativas de golfe para atribuições falsas dentro de uma lambda
- Explore novos leads para melhores métodos
Cada resposta deve explicar uma solução alternativa ou potencial lead.
lambda s:(s+s[::-1]).lower()
. Claro que isso não responde à pergunta real.strip
.Respostas:
eval
Isso não é tão bom por si só, mas se sua solução já usa
eval
de alguma forma ou forma, geralmente você pode usar essa técnica.fonte
Expressões de atribuição em Python 3.8
O Python 3.8 ( TIO ) introduz expressões de atribuição , que são usadas
:=
para atribuir uma variável embutida como parte da expressão.Isso pode ser usado dentro de a
lambda
, onde as atribuições geralmente não são permitidas. Comparar:Veja esta dica para mais.
fonte
Lambdas internas
Isso permite definir várias variáveis ao mesmo tempo.
vs.
é muito mais longo, mas se você tiver várias variáveis ou variáveis mais longas, que serão repetidas várias vezes:
vs.
Contador de caracteres
Inicial:
(lambda:)()
(11 bytes)Primeira variável:
[space]a
(2 bytes)Variáveis subsequentes:
,b,
(3 bytes)Use:
a
(1 byte).(Também economiza colchetes)
Então, isso leva
3n + 10
bytes, onden
é o número de variáveis. Esse é um alto custo inicial, mas pode render no final. Ele ainda retorna seu valor interno, para que você possa aninhar vários (embora isso rapidamente não valha a pena).Isso é realmente útil apenas para cálculos intermediários longos em compreensões de lista aninhadas, pois
def f():a=...;b=...;return
geralmente será mais curto.Para 1 valor, isso salva:,
uses * length - length - uses - 13
portanto, só é útil quando essa expressão é positiva.Para
n
expressões diferentes usadasu
vezes no total, onde está o comprimento combinadol
, isso economiza:l - (3 * n) - u - 10 ( + brackets removed )
fonte
Use uma lista
Declare uma lista como parâmetro e use
.append() or
para armazenar o valor: selambda s:s.lower()+s.lower()[::-1]
transforma em
lambda s,l=[]:l.append(s.lower())or l[-1]+l[-1][::-1]
Contador de caracteres:
,l=[]
5 caracteresl.append()or
13 caracteresl[-1]
5 caracteres para cada usoEmpatar
A quantidade de caracteres adicionados é:
uses*(5-length) + 18 + length
No exemplo anterior, a instrução
s.lower()
possui 9 caracteres e é usada 2 vezes. A aplicação dessa técnica adicionou 19 caracteres. Se fosse usado 7 vezes, haveria uma redução de 1 caractere.A quantidade mínima de usos para essa técnica vale a pena é
min_uses = (18+length)/(length-5)
Upsides
list
objeto para[0]
,.pop()
,[x:y]
e outras funções de lista pode ser usado para truques. altamente situacionalDesvantagens
5
Use um dicionário
thanks @Zgarb A
mesma ideia acima Declare um dicionário como parâmetro e use-o
.setdefault()
para armazenar (e retornar) o valor: selambda s:s.lower()+s.lower()[::-1]
transforma em
lambda s,d={}:d.setdefault(0,s.lower())+d[0][::-1]
Observe que, diferentemente da
list
contraparte,setdefault
retorna o valor atribuído.Contador de caracteres:
,d={}
5 caracteresd.setdefault(k,)
16 caracteresd[k]
4 caracteres para cada usoEmpatar
A quantidade de caracteres adicionados é:
(uses-1)*(4-length) + 21
No exemplo anterior, a instrução
s.lower()
possui 9 caracteres e é usada 2 vezes, aplicando esta técnica adicionamos 16 caracteres. Se fosse usado 7 vezes, haveria uma redução de 1 caractere.A quantidade mínima de usos para essa técnica vale a pena é
min_uses = 1-21/(4-length)
Upsides / Downsides
4
Outras considerações
lambda
é provável que ela possa ser descartada e a função ser reescrita comdef
/input
para um programa mais curto.fonte
lambda s,d={}:d.setdefault(0,s.lower())+d[0][::-1]
também é reutilizável.list.extend
para adicionar vários elementos ao mesmo tempo, que serão mais curtos do que usandolist.append
várias vezes.Use para definir variáveis e retornar os dados após a operação, como:
fonte
Compreensões de lista
Este é mais um último recurso, uma vez que é tão desagradável, mas você pode fazer
[<expression> for <variable> in <value>]
para pseudo-definir uma variável em uma lambda. Basicamente, o único ponto positivo desse método é que a expressão interna pode permanecer legível, o que obviamente é a menor preocupação para você quando joga golfe.
fonte