Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional list comprehension

I am trying to gain a better understanding of how list comprehensions work. I have the following function that returns true or false if a number is prime (which I found somewhere on the forum but cant 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]

in 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 is better to use the function in this case, but like I said I am trying to understand the list comprehension and its capabilities.

like image 797
Infinity Cliff Avatar asked Apr 04 '17 00:04

Infinity Cliff


1 Answers

You can do this:

[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 a good thing. IMO using a prime tester function like you do is better...

NOTE: what doesn't work in your try is that you modified the logic of your outer list comprehension. You still want a structure like [n for n in range(...) if (expression testing if n is prime)].

like image 156
Julien Avatar answered Oct 11 '22 14:10

Julien