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.
source to share
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)]
.
source to share
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.
source to share
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)]
source to share