Conditional lists

I am trying to get a better understanding of how lists work. I have the following function that returns true or false if the number is prime (which I found somewhere on the forum, but can't remember where):

import math

def is_prime(n):
    if n % 2 == 0 and n > 2: 
        return False
    for i in range(3, int(math.sqrt(n)) + 1, 2):
        if n % i == 0:
            return False
    return True

      

if i run:

[x for x in range(2, num) if is_prime(x)]

      

i get the desired result

[2, 3, 5, 7, 11, 13, 17, 19]

      

while trying to convert the whole function to a list comprehension, I came up with:

[x if not (x%2==0 and x > 2) else x for x in range (2, num) 
     for i in range(3, int(x**(1/2))+1, 2) if not (x%i==0)]

      

which produces:

[10, 11, 13, 14, 16, 17, 19]

      

not sure where i am going wrong and would appreciate some help. In truth, I think it's better to use a function in this case, but as I said, I'm trying to understand the understanding and capabilities of this list.

+3


source to share


3 answers


You can do it:

[n for n in range(2, num) if n % 2 != 0 and n > 2 and all(n % i != 0 for i in range(3, int(math.sqrt(n)) + 1, 2))]

      



although one liner just for the sake of it is not necessarily good. IMO using simple tester function like you is better ...

NOTE. What doesn't work in your attempt is that you changed the logic of your external list comprehension. You still need a type structure [n for n in range(...) if (expression testing if n is prime)]

.

+2


source


The main problem is that you are doing a complex translation. Try to simplify your initial condition so that you return "x if x == 2, else x ..." as you did. I'm just giving you a major hint; from what you've already done, I think you can figure it out.



If not, try simplifying the "else" statement so you can understand the logic behind this clause. Then I am sure you will get it. Are you fine.

0


source


In the above code, there are logical errors that are 1/2

evaluated as 0, not 0.5. To do this use either 0.5 or 1 / 2.0 or 1.0 / 2

Also it doesn't care about 2 as a special case. since (for i in range(3, int(x**(1/2.0))+1, 2) if not (x%i==0))

it is not executed

for i in range(3, int(x**(1/2.0))+1, 2) if not (x%i==0)

is also a logical error, as whenever this condition is true it causes multiple entries to be added

the right way would be

[x for x in range (2, num) if x == 2 or (x > 2 and x % 2 == 1 and len([i for i in range(3, int(x**(1/2.0))+1, 2) if x%i == 0 ])==0)]

      

0


source







All Articles