4 ms·
That translation is kind of why i don't like python list comprehensions though. It's often clearer as a for-loop or map/filter, cause the different predicates
by ebola1717 11y ago
That translation is kind of why i don't like python list comprehensions though. It's often clearer as a for-loop or map/filter, cause the different predicates are broken out into separate lines, rather than lumped together in one long line.
- sanderjd 11y agoI'm a big fan of just using map/filter, but I think it makes sense to wonder whether such a common and important operation is worth its own syntax. I do think the way nesting works is a bit surprising. It didn't really occur to me until reading an earlier comment that in essence the most nested loop is a `map` and all the others are `flatMap`s. (I think?)
- d0mine 11y agoThe way to understand how the nesting works in the list comprehension: L = [] for x in X: for y in Y: L.append(x*y) [loops] translate to L = [x*y for x in X for y in Y] If you understand the order of the loops in the first code fragment; you should understand the order in the second one -- it is the same order.
- dragonwriter 11y agoThe problem is that the relation of the body to the loop specifications is reversed, so the inner loop is most proximate to the body in the first, but most distant from the body in the second. The specification of the inner loop should always be most proximate to the body, not last independent of the location of the body.
- sanderjd 11y agoAs a person who thinks about this stuff in more functional terms, as in mapping over collections, rather than imperatively iterating and appending, it helps me to realize how it translates to map and flatMap rather than how it translates to for loops (which I already realized).
- d0mine 11y agoIt is not much easier to understand the explicit loop: doubled_odds = [] for n in numbers: if n % 2 == 1: doubled_odds.append(n * 2) compared to the list comprehension: doubled_odds = [n * 2 for n in numbers if n % 2 == 1] Here's the explicit loop without newlines for comparison: for n in numbers: if n % 2 == 1: doubled_odds.append(n * 2) Notice that the for-loop and the if-statement are in the same order in the loop and in the list comprehension. Only the value expression (n * 2) is out-of-order. OPs jumping around is often unnecessary in the gif. The one line list comprehension is as much readable for people familiar with Python as the variant with the explicit loop. It is not uncommon to use several list comprehensions in a function. If you rewrite them as explicit loops then it may increase the line count 4 times e.g., it can convert a simple 3-lines function that could be understood at a glance into 12 lines function that you have to read line by line to understand -- it is easy to keep track of 3 values on 3 lines but it is not clear whether it is true for 12 lines.
- iamsohungry 11y agoI think the problem here is that nested comprehensions and filter comprehensions are almost always too complex. If you are doing something that requires that, you should break it up and give the pieces names: odd_numbers = range(1, limit, 2) doubled_odd_numbers = [n * 2 for n in odd_numbers]
- viraptor 11y agoA good reason to use list comprehension for simple things though is that you can sometimes quickly change [...] to (...) and get an equivalent generator. With a loop, you'd have to extract it into a separate yielding function.
- msellout 11y agoPerhaps a for-loop is more similar to your memory of other code, but a list comprehension is more similar to an English sentence. "All names longer than 4 characters in the list of cities?" all(len(name) > 4 for name in cities) "Sum of x-squared for x from 10 to 20." sum(x**2 for x in range(10, 20))