[Tutor] stumped by what looks like recursive list comprehension

Steven D'Aprano steve at pearwood.info
Sun May 5 19:21:01 CEST 2013


On 06/05/13 02:56, Jim Mooney wrote:
> I looked up "list comprehension" after the last explanation and it's
> really cool. But the example below stumps me. I understand the second
> part, "primes =" but the first part, "noprimes =" baffles me since it
> swaps i and j back and forth in what looks like a circle ;')  Also,
> the other examples I looked at had a function of 'x' before the 'for,'
> and 'x' after, so they were easy to follow. But this example has 'j'
> as a function of 'i,' then 'i,' as a function of 'j' and has me dizzy.
>
> Could someone show this in normal, indented 'for' loops so I can see
> what 'for' goes where and how it works. I figure if I figure this one
> one I'll really comprehend list comprehension.
>
> # find nonprimes up to 50, then filter out what's left as primes
>
> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
> primes = [x for x in range(2, 50) if x not in noprimes]


The most important difference between a list comprehensions and it's equivalent for-loop is that the "body" of the loop (a single expression in the list comp case) is moved to the front of the list comp. So to convert the list comp back to a for-loop, move the initial expression just before the very first "for" to the very bottom of the loop(s). Everything else remains in the same order, just indented as needed.

So the noprimes list comprehension acts like this:


# noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
noprimes = []
for i in range(2, 8):
     for j in range(i*2, 50, i):
         noprimes.append(j)


The primes list comprehension acts like this:


# primes = [x for x in range(2, 50) if x not in noprimes]
primes = []
for x in range(2, 50):
     if x not in noprimes:
         primes.append(x)



-- 
Steven


More information about the Tutor mailing list