34
2
This is a tips question for golfing in Python.
In Python golfing, it's common for a submission to be a function defined as a lambda. For example,
f=lambda x:0**x or x*f(x-1)
computes the factorial of x.
The lambda format has two big advantages:
- The boilerplate of
f=lambda x:...
orlambda x:...
is shorter than thedef f(x):...return...
orx=input()...print...
- A recursive call can be used to loop with little byte overhead.
However, lambdas have the big drawback of allowing only a single expression, no statements. In particular, this means no assignments like c=chr(x+65)
. This is problematic when one has a long expression whose value needs to be referenced twice (or more).
Assignments like E=enumerate
are possible outside the function or as an optional argument, but only if they don't depend on the function inputs. Optional arguments like f=lambda n,k=min(n,0):...
fail because input n
hasn't been defined when k
is evaluated at definition time.
The result is that sometimes you suck up repeating a long expression in a lambda because the alternative is a lengthy non-lambda.
lambda s:s.strip()+s.strip()[::-1]
def f(s):t=s.strip();print t+t[::-1]
The break even point is about 11 characters (details), past which you switch to a def
or program
. Compare this to the usual break-even point of length 5 for a repeated expression:
range(a)+range(b)
r=range;r(a)+r(b)
print s[1:],s[1:]*2
r=s[1:];print r,r*2
Other languages have workarounds, Octave for example. There are known tricks for Python, but they are long, clunky, and/or limited-use. A short, general-purpose method to simulate assignment in a lambda would revolutionize Python golfing.
What are ways for a Python golfer to overcome or work around this limitation? What potential ideas should they have in mind when they see a long expression repeated twice in a lambda?
My goal with this tips question is to dive deep into this problem and:
- Catalog and analyze golfing workarounds to fake assignment inside a lambda
- Explore new leads for better methods
Each answer should explain a workaround or potential lead.
I'm guessing this is one of those things that can't be done well in Python. JavaScript has a leg up on this one. – mbomb007 – 2017-01-11T22:56:06.013
Just as with orlp's answer, Neil's (deleted) suggestion for using nested lambdas isn't necessarily longer than def in cases where you need a nested lambda anyway. I think it deserves more thorough analysis. – Martin Ender – 2017-01-12T07:54:36.400
2For the exact example given with the reversed lowercase string concatenation one could just go for
lambda s:(s+s[::-1]).lower()
. Of course this does not answer the actual question. – Jonathan Allan – 2017-01-12T17:35:01.777@JonathanAllan Good point, changed it to
strip
. – xnor – 2017-01-12T21:42:08.050