3 ms·
Two things that JS has over Python is lexical scoping and map/reduce/filter and lambda support. JS can be verbose, but I find that functional style JS is, in
by rajangdavis 8y ago
Two things that JS has over Python is lexical scoping and map/reduce/filter and lambda support.
JS can be verbose, but I find that functional style JS is, in my opinion, a bit more readable than Python list comprehensions.
- whalesalad 8y ago> Two things that JS has over Python is lexical scoping and map/reduce/filter and lambda support. ??? Python does all of that. There are native map/reduce/filter methods in the standard library. >>> x = [1, 2, None, 3] >>> list(filter(None, x)) [1, 2, 3] and then map >>> list(map(float, [1, 2, 3])) [1.0, 2.0, 3.0] Lambda's are everywhere in Python: >>> double = lambda x: x * 2 >>> list(map(double, range(3))) [0, 2, 4] https://docs.python.org/3/library/functions.html https://docs.python.org/3/library/functions.html
- rajangdavis 8y agoI know that they exist, but if you look at your examples, you have to manually cast maps into a list which is a bit strange coming from Ruby/JS/Scala. Once you have something sufficiently complex (such as using map, filter, and reduce all at the same time), there becomes so much line noise that it starts working against you. With JS/Ruby/Scala, you chain functional methods as opposed to Python where you can keep wrapping functions. Something like let arr = [0,1,2,'test']; arr .filter(x => typeof(x) == 'number') .map(x => x*2) .reduce((x, y) => x * y) becomes a little more cryptic with Python: from functools import reduce arr = [0,1,2,'test'] # with lambdas reduce(lambda x,y: x + y, map(lambda x: x * 2, filter(lambda x: type(x) == int, arr))) # list comprehension equivalent sum([x * 2 for x in arr if type(x) == int]) While Python is very beginner friendly, it has a really strange (in my opinion) approach to functional concepts. However, it is has other features that make it really nice to work with (like decorators, data classes, sets, robust ML libraries, really nice built ins).
- naveen99 8y agoChaining function calls makes things harder to debug, so I don’t do it.
- rajangdavis 8y agoI don't think it's any harder than broadcasting... I try to avoid chaining unless I know the structure of the data I am working with.
- goatlover 8y agoBroadcasting is even better than both for vector arithmetic and comparison operators, which is what you get with Python libraries built on top of NumPy arrays. > a = np.array([1, 2, 3, 4, 5]) > a * 10 array([10, 20, 30, 40, 50]) > a[a < 3] array([1, 2]) It's even nicer in languages with builtin vectors like R: > a1 = 1:5 > a2 = c(2, 4, 6, 8, 10) > a1 + a2 3 6 9 12 15 In Pandas, you can add a new dataframe column that's the result of arithmetic operations on other numeric columns. > df["New Column Name"] = df.Col1 * (df.Col2 / df.Col3)
- rajangdavis 8y agoTo each his own; I prefer JS/Ruby/Scala style map/filter/reduce functions for these sort of operations: let a = [1, 2, 3, 4, 5] > a.map(x => x * 10) (5) [10, 20, 30, 40, 50] > a.filter(x => x > 3) (2) [4, 5] > a1.map((x,i) => x + a2[i]) (5) [3, 6, 9, 12, 15] I don't hate broadcasting, but it can get a bit cryptic at times. Once the filtering starts getting complex, it can be a bit difficult to read unless you start breaking things out into variables and chaining filters together. For JS, something similar to pandas creating a new column based on operations of other columns would be to do map an array of objects (list of dicts) and use a (Schwartzian_transform)[https://en.wikipedia.org/wiki/Schwartzian_transform https://en.wikipedia.org/wiki/Schwartzian_transform] to create a new object property. I would love to look into how efficient these sort of operations can be, have had some success with this sort of thing for performing cosine similarity in the browser instead of creating sparse matrices with python.
- goatlover 8y agoI understand wanting to use map or filter when things get more complex. Pandas has filter and apply methods for that. I agree that the JS versions are quite nice with the arrow functions and method chaining. But for simpler operations, if you're doing a lot of vector computations, then map and filter bloat the code considerably when the mathematical notation is easy to read. Good luck with work on the JS implementation and efficiency comparisons. Pandas utilizes a Series object built on top of NumPy array for handling columns and rows. I don't know whether a similar approach would be helpful in JS.