2

I am preparing for my exam and I decided to start solving past exams. One of the requirements is to understand what a code does. But I am having troubles with this annotation.

I do not understand which the structure of this nested loop and which loop is executed first.

n = 10
p = [q for q in range(2, n) if q not in [r for i in range(2, int(n**0.5)) for r in range(i * 2, n, i)]]
print(p)

Can someone help me understand please?

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
Nancy
  • 29
  • 1

4 Answers4

1

It starts by evaluating:

[r for i in range(2, int(n**0.5)) for r in range(i * 2, n, i)]

which boils down to:

[r for r in range(4, 10, 2)]

since range(2, int(n * 0.5)) reduces to a list with a single element [2] that is used as the value of i in the for r in range(i * 2, n, i) statement. So the inner list comprehension evaluates to [4, 6, 8].

Then, the outer loop for q in range(2, n) is executed and it returns those elements from the list [2, 3, ..., 9] that do not belong in the previously constructed list i.e [4, 6, 8] with:

# range(2, n) -> [2, 3, ..., 9]
q for q in range(2, n) if q not in [..previously constructed list]     
Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
1

As a rule of thumb, the innermost loops are going to be executed first.

Having this in mind, let's break the problem down :

[r for i in range(2, int(n**0.5)) for r in range(i * 2, n, i)]

n**0.5 is 3.xxx, so range(2, int(n**0.5)) is in fact range(2, 3), which is 2 (see range for more informations).

So i is going to be 2, no matter what.

r in range(i * 2, n, i) looks pretty simple now, r will be between 4 and 10 (excluded), using a step of 2. The possible values are 4, 6 and 8.

The problem becomes :

p = [q for q in range(2, n) if q not in [4, 6, 8]]

Which is basically all odd numbers between 2 and 10 (excluded), plus the number 2.

3kt
  • 2,543
  • 1
  • 17
  • 29
0

This equivalent to :

list_i=[]
for i in range(2, int(n**0.5)):
    for r in range(i*2, n, i):
        list_i.append(r)
res=[]
for q in range(2, n) :
    if q not in list_i:
        res.append(q)

print res
khelili miliana
  • 3,730
  • 2
  • 15
  • 28
-1

If you're having a hard time understanding inner loops, run this code:

resultA = []
for x in ['x1', 'x2', 'x3']:
    for y in ['y1', 'y2', 'y3']:
        for z in ['z1', 'z2', 'z3']:
            resultA.append(''.join([x, y, z]))

print resultA

resultB = [''.join([x, y, z])
           for x in ['x1', 'x2', 'x3']
           for y in ['y1', 'y2', 'y3']
           for z in ['z1', 'z2', 'z3']
           ]

print resultB

print resultA == resultB

Once you've understood this code comprehension lists become second nature to you, then just come back to your original code and you won't have any problems with it :)

halfer
  • 19,824
  • 17
  • 99
  • 186
BPL
  • 9,632
  • 9
  • 59
  • 117