3 ms·
> The former is absolutely identical to the latter Oh, really? Let's compare: >>> absolute_0 = lambda path: path if path.startswith('/') else '/' + path
by merlincorey 11y ago
> The former is absolutely identical to the latter
Oh, really? Let's compare:
>>> absolute_0 = lambda path: path if path.startswith('/') else '/' + path
>>> def absolute_1(path):
... '''Return the absolute unix path from a given path name'''
... if not path.startswith('/'):
... path = '/' + path
... return path
>>> import dis
>>> dis.dis(absolute_0)
2 0 LOAD_FAST 0 (path)
3 LOAD_ATTR 0 (startswith)
6 LOAD_CONST 1 ('/')
9 CALL_FUNCTION 1
12 POP_JUMP_IF_FALSE 19
15 LOAD_FAST 0 (path)
18 RETURN_VALUE
>> 19 LOAD_CONST 1 ('/')
22 LOAD_FAST 0 (path)
25 BINARY_ADD
26 RETURN_VALUE
>>> dis.dis(absolute_1)
4 0 LOAD_FAST 0 (path)
3 LOAD_ATTR 0 (startswith)
6 LOAD_CONST 1 ('/')
9 CALL_FUNCTION 1
12 POP_JUMP_IF_TRUE 28
5 15 LOAD_CONST 1 ('/')
18 LOAD_FAST 0 (path)
21 BINARY_ADD
22 STORE_FAST 0 (path)
25 JUMP_FORWARD 0 (to 28)
6 >> 28 LOAD_FAST 0 (path)
31 RETURN_VALUE
These functions are actually not identical in their computation - only their result.
> 1) the former function does not know its own name
If you think that is really important (hint: it's not [from a lisper perspective, anyway]), Python thankfully allows you to do this:
>>> absolute_0.__name__
'<lambda>'
>>> absolute_0.__name__ = '<lambda "absolute_0">'
>>> absolute_0.__name__
'<lambda "absolute_0">'
> 2) the latter function can be documented with a docstring
>>> absolute_0.__doc__
>>> absolute_0.__doc__ = 'Return the absolute unix path from a given path name'
>>> help(absolute_0)
Help on function <lambda "absolute_0">:
<lambda "absolute_0">(path)
Return the absolute unix path from a given path name
Of course the only reason you can't put docstrings on a lambda function in python is because the forced indentation of code and implicit return with no indented block available is what Guido went with for Lambda.
> Considering that the creator of the Python language considered getting rid of lambdas
Guido is not a proponent of functional programming in general and claims that map, reduce, and filter are so much harder to understand than list comprehensions (which implement some common map, reduce, and filter, operations with special optimized syntax) that he tried to get them removed from the language too. Thankfully for us users of the language, this view did not win through and we can still use map, reduce, and filter in python, if we choose.
- aaronchall 11y agoSpare us the half-baked hackery. List comprehensions and generator expressions have replaced all need for map, filter, and lambdas, and are far more readable. For someone new to Python, halfway through LPTHW, they don't need those things. Hey, maybe you can help me decipher this, I've always wondered exactly what's going on here: https://docs.python.org/2/faq/programming.html#is-it-possible-to-write-obfuscated-one-liners-in-python https://docs.python.org/2/faq/programming.html#is-it-possibl... # Mandelbrot set print (lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y, Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM, Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro, i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y >=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr( 64+F(Ru+x*(Ro-Ru)/Sx,yc,0,0,i)),range(Sx))):L(Iu+y*(Io-Iu)/Sy),range(Sy ))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24) # \___ ___/ \___ ___/ | | |__ lines on screen # V V | |______ columns on screen # | | |__________ maximum of "iterations" # | |_________________ range on y axis # |____________________________ range on x axis
- merlincorey 11y ago> Spare us the half-baked hackery. Ad hominem? I guess I win. > List comprehensions and generator expressions have replaced all need for map, filter, and lambdas Please explain how list comprehensions and generators have replaced the need for lambdas. >>> sorted(((x, -(x**2)) for x in xrange(10) if 0 == x % 2), key=lambda item: item[1]) [(8, -64), (6, -36), (4, -16), (2, -4), (0, 0)] Your "distaste" of functional programming constructs is right up there with Guido's.
- aaronchall 11y agoNice lambda. You've defended yourself admirably. Did you know there's an `operator.itemgetter` function that does that? So that's: >>> sorted(((x, -(x**2)) for x in xrange(10) if 0 == x % 2), key=operator.itemgetter(1)) [(8, -64), (6, -36), (4, -16), (2, -4), (0, 0)] Do note that good code and code golf are two different things! :D