I try to create a shorter algorithms to guess if a number is a prime-number or not
So there is the algorithms that I want to short
def is_premier(n):
i=2
while i < n and n%i !=0:
i+=1
return i==n
And there is what I try to do:
def is_prime_v3(n):
return ("Non Prime" if n%i==0 else "Prime" for i in range(2,n))
But I don't know if this generator is correct or there is a way to get the string ? My real interest is not the prime number algorith, I try to figure out if is it possible to get something with this following structure ( return a if condition else b for x in range(n); and collect the answer a or b)
Thanks for answers
You didn't manage to translate the first function correctly, no.
The function is_premier()
returns a single boolean value, while is_prime_v3()
returns a generator of strings.
The is_prime_v3()
generator produces multiple "Prime"
values for non-prime numbers, e.g. for 8
, the test 8 % 3 == 0
is false, so "Prime"
is generated:
>>> list(is_prime_v3(8))
['Non Prime', 'Prime', 'Non Prime', 'Prime', 'Prime', 'Prime']
Using a conditional expression is the wrong tool here. The first function stops early when a condition is met, while your second loop never stops early, and only produces different values each iteration.
If you use a regular loop and print()
calls instead of yielding, this is what is executed:
for i in range(2, n):
if n % i == 0:
print("Non Prime")
else:
print("Prime")
That loop also never stops when n % i == 0
is found.
Now, it could have been your goal to do so, to produce Non Prime
and Prime
strings. However, it is easier if you used booleans instead, so True
and False
.
Your first function could be described, in English, as doing this:
i
at 2i
is smaller than n
and n % i != 0
is true, add one to i
.i
is equal to n
, we have a prime number!You could also use a range()
for that, and then it becomes:
i
from the range 2 to n
(not including n
).n % i == 0
is true, this is not a prime number.i
where n % i == 0
, we have a prime number!In code that is:
for i in range(2, n):
if n % i == 0:
return false
return true
For that kind of 'early exit' if a condition is met or not met, you can use the any()
or all()
functions. These work best with a generator, they test each value produced and return true
or false
early if the condition no longer holds.
E.g. for the case where all values of i
must not be a divisor, you can use:
def is_prime_generator(n):
return all(n % i != 0 for i in range(2, n))
Finally, your own attempt, is_prime_v3()
, could be made to do the same, if used as a utility function, where we don't require that all n % i != 0
tests are true, but that all strings are 'Prime'
:
>>> all(s == 'Prime' for s in is_prime_v3(8))
False
>>> all(s == 'Prime' for s in is_prime_v3(7))
True