8 ms·
Specifically?
by Lord_DeathMatch 10y ago
Specifically?
- hexane360 10y agoI think a big thing for many is the lambda: syntax, as well as the lack of full anonymous functions.
- NegativeLatency 10y agoI agree that typing out the word lambda is annoying, but you can use them as fully anonymous functions.
- masklinn 10y ago> you can use them as fully anonymous functions. 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.
- grondilu 10y agoYou can nest lambdas to get the equivalent of several expressions. I once wrote a Runge-Kutta example on Rosetta Code showing this: http://rosettacode.org/wiki/Runge-Kutta_method#using_lambda 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.
- masklinn 10y agoYou can but you still can't get statements in there.
- ergl 10y agoYou can hack together multiple expressions chaining them with and http://sigusr2.net/one-line-echo-server-using-let-python.html http://sigusr2.net/one-line-echo-server-using-let-python.htm...
- zardeh 10y agoThat still doesn't get you statements. You can't get context managers or exception handling (although you can raise exceptions) into lambdas, I've tried.
- masklinn 10y agoWell you might be able to if you add a bunch of named function combinators wrapping these, but definitely not with only lambdas, unless you define your combinators using `ast`, which I think would let you define statements via expressions.
- AnkhMorporkian 10y agoThat's an awful lot of effort to go to to avoid naming a function.
- zardeh 10y agoWell sure, you could do something like 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 :P
- masklinn 10y ago> but you can't do that itself as a lambda. And I consider modifying the ast cheating :P No disagreement, really depends whether you're a "rules" or "spirit" kind of person though.
- masklinn 10y agoThe latter can't really happen given Python is a statements- and indentations-based language. You'd need some really weird meta-magical syntax which really isn't going to happen in Python. Although you can cheat by fucking around with decorators e.g. 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)
- dragonwriter 10y ago> The latter can't really happen given Python is a statements- and indentations-based language. 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.
- saadq 10y agoNot really a fan of the lambda syntax in Python. Comparison: 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
- brianwawok 10y agoIs there a more Pythonic way to do it? Lambdas are cool but usually not the first place you go in Python. I would think something like (my best guess, not a Python pro)... 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
- FreeFull 10y agoI would write it like this, to avoid constructing the immediate list: sum_of_squares = sum(x*x for x in arr) This makes use of https://www.python.org/dev/peps/pep-0289/ https://www.python.org/dev/peps/pep-0289/
- brianwawok 10y agoThanks for the link, this is good to know.
- akavi 10y agoWhat's the advantage of list comprehension over lambdas (assuming the lambda syntax is decently lightweight)? 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.
- brianwawok 10y agoI think it's just less to type really, and it's considered the more standard way to do it.
- jpulec 10y agoI think lambda syntax can be a bit cumbersome, but that aside what I really miss is a clean syntax for chaining functional operations. So often I find myself thinking about data in terms of 'pipelines'. i.e. in JS: _.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.
- SoftwareMaven 10y agoBut that's a function of API, not the language itself. Django (and most ORMs, I believe) support that kind of behavior: 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.py https://github.com/serkanyersen/underscore.py The 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.
- chris_7 10y agoThis sort of API is hard to implement in Python though, because there's no formal notion of interfaces, so you cannot extend all iterables generically. So you need to use free functions (which don't read well when chained) or a wrapper object (ick).
- hcrisp 10y agoYou don't like using pytoolz? Pseudocode: result = pytoolz.pipe(values, map, flatten, compact, uniq, value) # or func = pytoolz.compose(value, uniq, compact, flatten, map) results = func(values)
- Bromskloss 10y agoLooks interesting. How do you tell map what function to use?