Esta es una pregunta de consejos para jugar golf en Python.
En el golf de Python, es común que un envío sea una función definida como lambda. Por ejemplo,
f=lambda x:0**x or x*f(x-1)
calcula el factorial de x.
El formato lambda tiene dos grandes ventajas :
- La repetitiva de
f=lambda x:...olambda x:...es más corta que ladef f(x):...return...ox=input()...print... - Se puede usar una llamada recursiva para hacer un bucle con una pequeña sobrecarga de bytes.
Sin embargo, las lambdas tienen el gran inconveniente de permitir solo una sola expresión, sin declaraciones. En particular, esto significa que no hay tareas como c=chr(x+65). Esto es problemático cuando uno tiene una expresión larga cuyo valor necesita ser referenciado dos veces (o más).
Las asignaciones como E=enumerateson posibles fuera de la función o como argumento opcional, pero solo si no dependen de las entradas de la función. Argumentos opcionales como f=lambda n,k=min(n,0):...error porque la entrada nno se ha definido cuando kse evalúa en el momento de la definición.
El resultado es que a veces apestas repetir una expresión larga en una lambda porque la alternativa es una larga no lambda.
lambda s:s.strip()+s.strip()[::-1]
def f(s):t=s.strip();print t+t[::-1]
El punto de equilibrio es de aproximadamente 11 caracteres ( detalles ), pasado el cual cambia a un defo program. Compare esto con el punto de equilibrio habitual de longitud 5 para una expresión repetida:
range(a)+range(b)
r=range;r(a)+r(b)
print s[1:],s[1:]*2
r=s[1:];print r,r*2
Otros idiomas tienen soluciones alternativas, por ejemplo , Octave . Hay trucos conocidos para Python, pero son largos, torpes y / o de uso limitado. Un método breve y de propósito general para simular la asignación en una lambda revolucionaría el golf de Python.
¿Cuáles son las formas para que un golfista de Python supere o evite esta limitación? ¿Qué ideas potenciales deberían tener en mente cuando ven una expresión larga repetida dos veces en una lambda?
Mi objetivo con esta pregunta de consejos es profundizar en este problema y:
- Cataloga y analiza soluciones de golf para falsificar tareas dentro de una lambda
- Explore nuevos clientes potenciales para obtener mejores métodos
Cada respuesta debe explicar una solución alternativa o potencial cliente potencial.

lambda s:(s+s[::-1]).lower(). Por supuesto, esto no responde la pregunta real.strip.Respuestas:
evalEsto no es tan bueno en sí mismo, pero si su solución ya se usa
evalde alguna manera o forma, generalmente puede usar esta técnica.fuente
Expresiones de asignación en Python 3.8
Python 3.8 ( TIO ) introduce expresiones de asignación , que se utilizan
:=para asignar una variable en línea como parte de la expresión.Esto se puede usar dentro de a
lambda, donde las asignaciones no se permiten normalmente. Comparar:Vea este consejo para más.
fuente
Lambdas interiores
Estos le permiten definir múltiples variables a la vez.
vs.
es mucho más largo, pero si tiene múltiples variables, o variables que son más largas, que se repiten muchas veces:
vs.
Número de letras
Inicial:
(lambda:)()(11 bytes)Primera variable:
[space]a(2 bytes)Variables posteriores:
,b,(3 bytes)Uso:
a(1 byte).(También ahorra entre paréntesis)
Entonces, esto toma
3n + 10bytes, dondenes el número de variables. Este es un alto costo inicial, pero puede pagar al final. Incluso devuelve su valor interno, por lo que puede anidar múltiples (aunque esto rápidamente no valdrá la pena).Esto realmente solo es útil para cálculos intermedios largos en comprensiones de listas anidadas, ya
def f():a=...;b=...;returnque generalmente será más corto.Para 1 valor, esto guarda:,
uses * length - length - uses - 13por lo que solo es útil cuando esa expresión es positiva.Para
ndiferentes expresiones utilizadasuen total, donde su longitud combinada esl, esto guarda:l - (3 * n) - u - 10 ( + brackets removed )fuente
Use una lista
Declarar una lista como parámetro y usar
.append() orpara almacenar el valor: selambda s:s.lower()+s.lower()[::-1]convierte en
lambda s,l=[]:l.append(s.lower())or l[-1]+l[-1][::-1]Número de letras:
,l=[]5 caracteresl.append()or13 caracteresl[-1]5 caracteres para cada usoCubrir los gastos
La cantidad de caracteres añadidos es:
uses*(5-length) + 18 + lengthen el ejemplo anterior, la declaración
s.lower()tiene 9 caracteres de longitud y se usa 2 veces, aplicando esta técnica se agregaron 19 caracteres. Si se usara 7 veces, habría una reducción de 1 carácter.La cantidad de usos mínimos que vale esta técnica es
min_uses = (18+length)/(length-5)Al revés
listobjeto de modo[0],.pop(),[x:y]y otras funciones de la lista se puede utilizar para hacer trucos. altamente situacionalDesventajas
5Usa un diccionario
gracias @Zgarb
Misma idea que la anterior Declarar un diccionario como parámetro y usar
.setdefault()para almacenar (y devolver) el valor: selambda s:s.lower()+s.lower()[::-1]convierte en
lambda s,d={}:d.setdefault(0,s.lower())+d[0][::-1]Tenga en cuenta que, a diferencia de la
listcontraparte,setdefaultdevuelve el valor asignado.Número de letras:
,d={}5 caracteresd.setdefault(k,)16 caracteresd[k]4 caracteres para cada usoCubrir los gastos
La cantidad de caracteres agregados es:
(uses-1)*(4-length) + 21En el ejemplo anterior, la declaración
s.lower()tiene 9 caracteres de longitud y se usa 2 veces, aplicando esta técnica se agregaron 16 caracteres. Si se usara 7 veces, habría una reducción de 1 carácter.La cantidad de usos mínimos que vale esta técnica es
min_uses = 1-21/(4-length)Ventajas / desventajas
4Otras Consideraciones
lambdaprobablemente se puede descartar y la función se puede reescribir condef/inputpara un programa más corto.fuente
lambda s,d={}:d.setdefault(0,s.lower())+d[0][::-1]también es reutilizable.list.extendpara agregar varios elementos a la vez, lo que será más corto que usarlist.appendvarias veces.Se usa para establecer variables y devolver los datos después de la operación de la siguiente manera:
fuente
Lista de comprensiones
Este es más un último recurso, ya que es muy infiel, pero puedes hacer
[<expression> for <variable> in <value>]para seudo-establecer una variable en una lambda. Básicamente, el único punto bueno de este método es que la expresión interna puede seguir siendo legible, lo que obviamente es lo que menos le preocupa al jugar golf.
fuente