[1, 2, 3, 4].map(x => x * x).filter(x => x < 10)
Python's lambdas and list comprehensions are quite restrictive in comparison to functional style. filter(lambda x: x < 10, map(lambda x: x * x, [1, 2, 3, 4]))
But even for more complicated logic, it also doesn't seem like it's that burdensome to just throw a name on the lambda: def square(x):
return x * x
def less_than_ten(x):
return x < 10
filter(less_than_ten, map(square, [1, 2, 3, 4]))
Which I find to be more readable/maintainable.That's probably the most underrated feature of python. Decisions about how the language should function like this which seem "restrictive" from one perspective, and yet force you down the avenue of good decision-making for readability/maintainability. Sure, it's possible to write terrible python, but you're generally cutting against the grain to do it.
Python's problem isn't a lack of lambdas, it's a lack of consistency; for some things you use functions and for others methods.
You can express the above as:
[x * x for x in [1, 2, 3, 4] if x < 10]
Which in set notation is {x^2 : x in (1, 2, .., 4), x < 10}.
[x * x for x in [1, 2, 3, 4] if x * x < 10]
There is a subtle shift in semantics. The functional form defines a sequence of function applications whereas the list comp notation is more of a declaration.
x = [1, 2, 3, 4]
x = map(lambda x: x*x, x)
x = filter(lambda x: x < 10, x)
x = list(x)
Or is there a more elegant way?```py x = [xx for x in [1, 2, 3, 4] if xx < 10] ```
[x [asterisk] x for x in [1,2,3,4] if x[asterisk] x < 10]
which is still a little annoying because the x [asterisk] x gets computed twice. This is one of those little details that really annoys mathematicians, as I saw with SageMath for decades (I started SageMath -- which uses Python -- and got no end of complaints about the above). In the Magma programming language there is a "where" version of comprehensions that eloquently solves this problem as explained here: http://magma.maths.usyd.edu.au/magma/handbook/text/10
For example,
{ xx : x in [1 .. 4] | xx lt 10 where xx is x*x}
which you can try at http://magma.maths.usyd.edu.au/calc/
You can escape asterisks with a backslash. \* => *
from itertools import repeat
from operator import pow,gt
x = list(filter(partial(gt,10), map(pow, [1, 2, 3, 4], repeat(2))))
(please don't do this)