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.
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.
odd_numbers = range(1, limit, 2)
doubled_odd_numbers = [n * 2 for n in odd_numbers] 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.The specification of the inner loop should always be most proximate to the body, not last independent of the location of the body.
"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))