3 ms·
len(list(filter(lambda line: all([abs(x) >= 1 and abs(x) <= 3 for x in line]) and (all([x > 0 for x in line]) or all([x < 0 for x in line])), diffs))) This rea
by chrismorgan 1y ago
len(list(filter(lambda line: all([abs(x) >= 1 and abs(x) <= 3 for x in line]) and (all([x > 0 for x in line]) or all([x < 0 for x in line])), diffs)))
This really isn’t fair on Python. Python isn’t very much not designed for this style of functional programming. Plus you haven’t broken lines where you could. Rewrite it as a list comprehension and add line breaks, and turn the inner list comprehensions into generator expressions (`all([…])` → `all(…)`), and change `abs(x) >= 1 and abs(x) <= 3` to `1 <= abs(x) <= 3` (thanks, Jtsummers), and it’s much better, though it still has the jumping around noted, and I do prefer the functional programming approach. I’m just saying the presentation isn’t fair on Python.
len([line for line in diffs
if all(1 <= abs(x) <= 3 for x in line)
and (all(x > 0 for x in line) or all(x < 0 for x in line))])
(Aside: change the first line to `sum(1 for line in diffs` and drop the final `]`, and it will probably perform better.)
I also want to note, in the JS… Math.abs(x) instead of x.abs() (as seen in Rust).
And, because nerd sniping, two Rust implementations, one a direct port of the JS:
diffs.iter().filter(|line| {
line.iter().all(|x| x.abs() >= 1 && x.abs() <= 3) &&
(line.iter().all(|x| x > 0) || line.iter().all(|x| x < 0))
}).count()
(`x.abs() >= 1 && x.abs() <= 3` would be better as `(1..=3).contains(x.abs())` or `matches!(x.abs(), 1..=3)`.)
And one optimised to only do a single pass:
diffs.iter().filter(|line| {
let mut iter = line.iter();
let range = match iter.next() {
Some(-3..=-1) => -3..=-1,
Some(1..=3) => 1..=3,
Some(_) => return false,
None => return true,
};
iter.all(|x| range.contains(x))
}).count()
- Jtsummers 1y agoabs(x) >= 1 and abs(x) <= 3 Is also unidiomatic in Python. 1 <= abs(x) <= 3 Means the same thing and tightens it up a bit, and reads better since it's indicating that you're testing if something is in a range more clearly. EDIT: To add: The filter, list construction, and len aren't needed either. It's just: sum(map(predicate, diffs)) # this counts the number of elements in diffs which satisfy predicate, map is lazy so no big memory overhead Or alternatively: sum(predicate(diff) for diff in diffs) The predicate is complex enough and used twice, so it warrants extraction to its own named function (or lambda assigned to a variable), but even if it were still embedded this form would be slightly clearer (along with adding the line breaks and removing the extra list generations): sum(map(lambda line: all(1 <= abs(x) <= 3 for x in line) and (all(x > 0 for x in line) or all(x < 0 for x in line)), diffs))
- chrismorgan 1y agoOoh yes, thanks, I didn’t even think about that, I was too focused on the other parts. Much nicer, updated.
- PaulHoule 1y agoThe author's argument is a strong argument against the way Lisp does it, at least for most code, as Lisp tends to put the verb to the left and nouns to the right so your IDE has no idea what nouns you are working with until you've picked the verb.
- kazinator 1y agoPretty much every functional language is verb-initial, as are function calls as well as statements in most mainstream languages. Verb-final languages like PostScript and Forth are oddballs. Embedded verbs are a thing of course, with the largest contribution coming from arithmetic expressions with infix operators, followed by certain common syntax like "else" being in the of an "if" statement, followed by things like these Python comprehensions and <action> if <condition> syntactic experiments and whatnot.
- PaulHoule 1y agoRight, his argument is in favor of the "fluent" syntax like table.where(...).select(...) that is typical in many OO interfaces, though you sometimes see a pipe syntax which would be autocomplete friendly in languages like Clojure https://clojuredocs.org/clojure.core/-%3E https://clojuredocs.org/clojure.core/-%3E or F# https://stackoverflow.com/questions/12921197/why-does-the-pipe-operator-work https://stackoverflow.com/questions/12921197/why-does-the-pi...