JavaScript:
let arr = [1, 2, 3]
let sumOfSquares = arr.map(n => n * n).reduce((a, b) => a + b) // 14
Python: arr = [1, 2, 3]
sum_of_squares = reduce(lambda a, b: a + b, map(lambda n: n * n, arr)) # 14 sum_of_squares = sum([x*x for x in arr])
Which I think is easier to read than either example post above.Of course you will point out that this is less powerful than full map and reduce.. but meh... pros and cons to both styles
sum_of_squares = sum(x*x for x in arr)
This makes use of https://www.python.org/dev/peps/pep-0289/I feel like I come down hard on the side of lambdas, but I've never really spent enough time in a language with list comprehension, so there's a good chance I'm missing something.
In theory I suppose the VM could have a map() implementation which opportunistically extracts the code from a lambda and inlines them when possible; but doubt CPython does that. OTOH, I'd be surprised if PyPy doesn't do something like that.
[1] http://python-history.blogspot.com/2010/06/from-list-compreh...
When doing something like `map(lambda x: 2+x, range(100))`, there will be 101 frames created: the outer frame, and 100 for each invocation of the lambda.
Whereas `[2+x for x in range(100)]` will only create 2: one for the outer frame, and one for the comprehension.
I'm from a non-list-comprehension background too, but recently started working a lot in a large python codebase, and have found the dict/list comprehensions to be beautiful. I'm a huge fan. It's a shame lambda syntax is not the best and it's generally crippled, but comprehensions are a great 80/20 compromise for handling most cases very cleanly.
In fact I had "reduce" appearing in the names of some of my variables so I used it less than 32 times, about 20 times in that project.
Could you show your reduce calls?
It's more than just stylistic.
But hey, if you want to use map when you actually need to do a parallel map, cool. But seems very very uncommon. ~ 1 in 10,000 maps I write.
from operator import mul, add
arr = [1, 2, 3]
sum_of_squares = reduce(add, map(mul, arr, arr)) (defn sum-of-squares [a] (reduce + (map #(* % %) a)))
(sum-of-squares [1, 2, 3]) ; => 14 _.chain(values)
.map(() => {})
.flatten()
.compact()
.uniq()
.value()
vs Python where doing the same thing becomes either a nested mess of function calls or comprehensions or a for loop. MyTable.objects.
filter(some_row__gt=5).
exlude(other_row='q').
order_by('other_row')
The Python iterable APIs have decided to use nesting rather than chaining, but you can still have an underscore-like API: https://github.com/serkanyersen/underscore.pyThe bigger problem remains: lambda functions are hideous in Python. map() will forever be ugly if you try to use it in the same way it is used in most functional languages.
result = pytoolz.pipe(values, map, flatten, compact, uniq, value)
# or
func = pytoolz.compose(value, uniq, compact, flatten, map)
results = func(values) pytoolz.curried.map(fn) values |> map(&({})) |> flatten |> compact |> uniq
Although, the closure syntax is a little clunky before you get used to it.A lambda can only contain a single expression, by "full anonymous function" I'm guessing hexane360 means multiple statements. You can't put a for loop or a context manager in a lambda for instance.
http://rosettacode.org/wiki/Runge-Kutta_method#using_lambda
It does not look as bad as one might expect, though the nesting of parenthesis makes things messy.
You can't get context managers or exception handling (although you can raise exceptions) into lambdas, I've tried.
def apply_ctx(ctx, func, *func_args, **func_kwargs):
with ctx as __ctx:
func(*func_args, **func_kwargs, ctx=__ctx)
but you can't do that itself as a lambda.
And I consider modifying the ast cheating :PNo disagreement, really depends whether you're a "rules" or "spirit" kind of person though.
def postfix(fn, *args):
return lambda arg: fn(arg, *args)
@postfix(map, range(5))
def result(i):
return i * i
print result
# [0, 1, 4, 9, 16]
(`postfix` is necessary because `map` takes its argument positionally so it's not possible to pass in the sequence with functools.partial)Yeah, though I suppose you could hack around that and get nearly-full functionality in lambdas if you built a library that either wrapped non-expression statements in functions or provided equivalent functions. There are obviously some statements that there aren't good solutions for in that direction.
OTOH, using named functions is in many cases more readable -- in the context of what is otherwise a normal Python codebase -- than the kind of lambdas that you can't easily write in Python. But I like the Coconut approach of but providing a more concise syntax for the kind of lambdas Python already supports.