简体   繁体   中英

Python while-loop for prime number returning unexpected value

I am trying to find the largest prime number in a list (ascending order). I created a while-loop which checks if a number in the list is prime by dividing it by each number less than itself and 'breaking' the loop when it finds a number that has no factor less than itself (greater than 1). This loop is nested in another while-loop which iterates backward through the list.

When I run the code, it keeps returning the number 8 (which is obviously not prime).

I have tried going through the code step-by-step on paper, inserting the variable values and doing the math. I must be miscalculating something.

factors = [2, 3, 4, 6, 8]
b = 1
y = len(factors) - 1
x = factors[y]
z = x - b

while y >= 0:
    while b < x:
        if x % z == 0:
            break
        else:
            if b == x-1:
                print(f'The number {x} is the largest prime in the list')
                break #need to end the outer loop here
            else:
                b +=1   
    y -= 1
    b = 1
print('There were no prime numbers in the list')

I expect the code to return 'The number 3 is the largest prime in the list'

What it actually returns:

The number 8 is the largest prime factor
The number 8 is the largest prime factor
The number 8 is the largest prime factor
The number 8 is the largest prime factor
The number 8 is the largest prime factor

A few main problems with your code:

  1. You are not updating the values of x (outer loop) and z (inner loop) on each iteration. You will want to add for z :
else:
    b += 1
    z = x - b

and for x :

y -= 1
x = factors[y]
b = 1
  1. The fact that you are having that many variables for that task makes it hard to read and understand. You could for example get rid of z all together and simply start b from 2 and go up.

  2. Since both loops iterate over a known range (outer on the list, inner until x ) it would be better to use for loops instead of while . That will also arrange your variables better. For example:

factors = [2, 3, 4, 6, 8]

for number in factors[::-1]:
    for b in range(2, number):
        if number % b == 0:
            break
        elif b == number-1:
            print(f'The number {number} is the largest prime in the list')
            break # you should put this whole code in a function and return here

print('There were no prime numbers in the list')

Notice that we don't use any other variables except the ones defined by the loops. That makes the code more readable.

The factors[::-1] means we are looping over the list in reverse order.


A nice little python feature is adding an else clause on a loop . This else will be executed only if the loop is exhausted without meeting any break statement. Which is perfect in our case because if the inner loop is exhausted, then the number is a prime for sure. So it can be:

factors = [2, 3, 4, 6, 8]

for number in factors[::-1]:
    for b in range(2, number):
        if number % b == 0:
            break
    else:
        print(f'The number {number} is the largest prime in the list')
        break # This now breaks the outer loop

else:
    print('There were no prime numbers in the list')

Note the use of that same technique also in the outer-loop, as if the inner loop exhausted without hitting the break in the else block, it means no prime was found so we want to print the no-found message.

Can you check the below codes please?

def prime_numbers(numbers):
    for i in numbers:
        for j in range(2, i):
            if i % j == 0:
                break
        else:
            yield i


try:            
    print(f"{max(prime_numbers([2, 3, 5, 6, 8]))} is the largest prime number.")
except ValueError:
    print("There are no prime numbers in the list.")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM