1

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

2
  • 1
    Yes, it's possible. You used a conditional expression (a if cond else b) correctly; it doesn't matter here that it's inside a generator expression. Commented Feb 2, 2021 at 11:25
  • 1
    However, your translation from is_premier() to is_prime_v3) is incorrect. You are generating a series of "Non Prime" and "Prime" strings with no filtering. E.g. 7 is prime, and so you generate the sequence 'Prime', 'Prime', 'Prime', 'Prime', 'Prime'. 8 is not prime, but your function outputs 'Non Prime', 'Prime', 'Non Prime', 'Prime', 'Prime', 'Prime'. Commented Feb 2, 2021 at 11:29

3 Answers 3

2

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:

  • Start i at 2
  • as long as i is smaller than n and n % i != 0 is true, add one to i.
  • if i is equal to n, we have a prime number!

You could also use a range() for that, and then it becomes:

  • Take i from the range 2 to n (not including n).
  • if ever n % i == 0 is true, this is not a prime number.
  • if we never found a value for 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
Sign up to request clarification or add additional context in comments.

1 Comment

Detailed answer, but I think you meant as long as i is smaller than n instead of i.
2

Your direction is good, but your expression returns a series of strings instead of a single value.

Looking at your original code, it basically says: if any number less than n divides n - return False. Otherwise True.

So this directly translates to Python as:

def is_prime(n):
    return not any(n%i == 0 for i in range(2,n))

Which is also equivalent to:

def is_prime_v3(n):
    return all(n%i != 0 for i in range(2,n))

Comments

2

If you want to reproduce the same logic (i.e. i advances up to n stopping on first divisor), you could formulate it like this:

def is_prime(n):
    return "Prime" if next(i for i in range(2,n+1) if n%i == 0) == n else "Non Prime"

or you could let the next() function select the string for you:

def is_prime(n):
    return next(("Non Prime" for i in range(2,n) if n%i == 0),"Prime")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.