This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 2 years ago.
Can you tell me why my fundamental Python program doesn't run properly. First I have a isprime module:
def isPrime(value):
count = 0
for i in range(1, value + 1):
if value % i == 0:
count += 1
if count == 2:
return True
else:
return False
and I import it to the PrimeFinder.py:
from isPrime import isPrime
lst = []
NumberOfValue = int(input())
for i in range(1, NumberOfValue + 1):
value = int(input())
lst.append(value)
for value in lst:
if isPrime(value) == False:
lst.remove(value)
print(lst)
But when I input:
the result also include non-prime numbers, can you explain if I was wrong in somewhere, thanks a lot for you help
from isPrime import isPrime
lst = []
NumberOfValue = int(input())
for i in range(1, NumberOfValue + 1):
value = int(input())
if isPrime(value):
lst.append(value)
print(lst)
Change the code to this, it will work. .remove will not remove the value from the list
Appears you should be doing
for i in range(1, NumberOfValue + 1):
value = int(input())
if isPrime(value):
lst.append(value)
Otherwise, you're modifying a list while iterating, and therefore skipping over some indicies and leaving elements behind
Regarding the efficiency of your isPrime function, there are better ways isPrime Function for Python Language
Related
This question already has answers here:
Why does my recursive function return None?
(4 answers)
Closed last month.
i = 1
input_number = int(input("Input a digit you wish to count: "))
def count(n):
global i
n = int(n/10)
if n > 0:
i = i+1
count(n)
else:
j = i
print(f"j={j}")
return j
j = count(input_number)
print(f"i={i}")
print(j)
I'm trying to use a recursive way to print the digits of a number. I used a global counter to count, and can print the global counter as result. However, my question is - why can't I make the function to return the counter and print the function result directly? It returns None somehow.
The count function does not always return a value, so in those cases, it returns None.
If n is greater than 0, no return is encountered.
if n > 0:
i = i+1
count(n)
You were likely wanting:
if n > 0:
i = i+1
return count(n)
Please also note that if you want integer division, you can use //. E.g. n = int(n/10) can be n = n // 10 or just n //= 10.
This question already has answers here:
What is the best way to get all the divisors of a number?
(18 answers)
Closed 2 years ago.
I am trying to write a Python script that will find prime numbers. In the way that I am going about this, the script is going to take a number from a range, determine the factors, determine if the only two factors are 1 and itself, and return true if it's a prime number. I need help with my code to find the factors.
num = int(input("enter: "))
i = 1
while i < num:
if num % i == 0:
print(i)
i += 1
else:
pass
The i is set to 1 because you can't divide by 0. However, the return starts to work, however, it only returns a couple of numbers, not the full list that I am hoping for. For example, you input 20, it returns only 1 and 2.
You're only incrementing i in the "is even" case. This'd fix it:
num = int(input("enter: "))
i = 1
while i < num:
if num % i == 0:
print(i)
i += 1
However, it's better to use range() for iterating over a range of numbers:
num = int(input("enter: "))
for i in range(1, num):
if num % i == 0:
print(i)
I am about to execute a function which aim is to return a Prime/Not prime statement if its argument is or isn't a prime number. I succeeded using a for loop:
def prime1(n):
z = []
for i in range (1, n+1):
if (n/i).is_integer():
z.append(i)
i=i+1
if len(z) == 2:
print ("Prime")
else:
print ("Not prime")`
Then I tried to do the same but using the while loop:
def prime2(n):
z = []
i = 1
while i < int(len(range(1, n+1))):
if (n/i).is_integer():
z.append(i)
i=i+1
if len(z) == 2:
print ("Prime")
else:
print ("Not prime")
Unfortunately, my system continues to calculating without printing me an output.
Can you explain me where I have made a mistake?
The i = i + 1 does nothing in your for loop, since the value of i is overwritten with the next value of the iterator; effectively, the for loop is performing i = i + 1 for you on every iteration, whether or not i divides n. You need to do the same thing in your while loop:
while i < n + 1:
if (n/i).is_integer():
z.append(i)
i = i + 1
The most pythonic way I could think of is below:
def isPrime(n):
return all(n % i for i in range(2, int(n ** 0.5) + 1)) and n > 1
for i in range(1, 20):
print(isPrime(i))
Explanation:
all makes sure that every item in the given expression returns True
n % i returns True if n != 0 (even negative numbers are allowed)
int(n ** 0.5) is equivalent to sqrt(n) and as range always returns numbers up to n - 1 you must add 1
n > 1 makes sure that n is not 1
The problem in your code is that your i = i + 1 in the wrong scope
Your program checks if (n/i).is_integer() which returns False as n / 2 is not a integer
Improving your code:
Instead of (n/i).is_integer() you can use n % i == 0, which returns the remainder equals 0
Next you must place i = i + 1 in the outer scope
And personally, I was never a fan of i = i + 1. Use i += 1
I think the best way is using the code I have shown above.
Hope this helps!
Edit:
You can make it print 'Prime' or 'Not Prime' as follows:
def isPrime(n):
print('Prime' if all(n % i for i in range(2, int(n ** 0.5) + 1))
and n > 1 else 'Not Prime')
for i in range(1, 20):
isPrime(i)
You are increment the iterable variable i inside the if statement, so the variable is never incremented, stucking on an infinite loop.
When you used for it worked because the iterable changes itself after every full iteration of the block.
Moving the incremenf of i one identation block to the left (inside the while instead of for) will work just fine
Code adapted from https://www.programiz.com/python-programming/examples/prime-number
You don't need to check until num and you can go 2 by 2 if you don't have a database of prime numbers
import math
#num = 437
if num > 1:
# check for factors
for i in range(2, int(math.ceil(math.sqrt(num))), 2):
if (num % i) == 0:
print(num, "is not a prime number")
print(i, "times", num // i, "is", num)
break
else:
print(num, "is a prime number")
# if input number is less than
# or equal to 1, it is not prime
else:
print(num, "is not a prime number")
Our preferred method should not be while loops if we don't need to use them, that being said, we could use list comprehensions:
def prime(n):
z = []
[z.append(i) for i in range(1, n+1) if (n/i).is_integer()]
[print("Prime") if len(z) == 2 else print("Not Prime")]
prime(101)
But lets take a loop at what you got your for loop:
for i in range (1, n+1):
if (n/i).is_integer():
z.append(i)
i=i+1
The line i = i + doesn't serve the purpose you intend, the loop is going to iterate from 1 to n+1 no matter what
Now the while loop:
while i < int(len(range(1, n+1))):
if (n/i).is_integer():
z.append(i)
# i=i+1 does not go inside if statement
i += 1
Now you do need to increment i but if that incrementing only occurs when the if conditions are met, then if the if condition is not met you are going to be stuck at the same i looping over it.
Also try using i += 1 means the same thing
This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 4 years ago.
Created a program to find prime factors of a natural number but i get an error:
multipliers = []
a = 2
value = input("Put a natural number here: ")
value = int(value)
for i in range(1, value):
if value % i == 0:
multipliers.append(i)
for x in multipliers:
while a < x:
if x % a == 0:
multipliers.remove(x)
else:
a += 1
print(multipliers)
All I want to do here is: Get an input value, find the multipliers of a value and make a list from them, take theese multipliers 1 by 1 and try to divide by [2, 3, 4, 5...], if a is a multiplier of x delete it from the list and get another value from list as x and do the same.
But when I try to run this i get an error message that says
ValueError: list.remove(x): x not in list
I don't know where am I doing wrong. Can you please help me?
Because x is removed from the list - then the while loop loops again and it tries to remove x from the list again.
To fix this add a break in your while loop like so:
for x in multipliers:
while a < x:
if x % a == 0:
multipliers.remove(x)
break
else:
a += 1
You could also replace the second for loop with a list comprehension:
factors = [x for x in multipliers if all(x % a != 0 for a in range(2, x))]
Beginner. I'm trying to return a list that includes all the prime numbers from 0 to num. Could someone please help me find what's wrong with my code? I always get an empty list. Thanks a lot! (I'm using python 3.6)
def task(num):
num = int(num)
lst = []
if num < 3:
return lst
else:
for i in range(3,num):
if not i & 1:
lst = lst
else:
primetest = range(3, int(i ** 0.5) + 1, 2)
for n in primetest:
if i % n != 0:
lst.append(i)
return lst
task(5)
Updates:
Thank you guys for all your comments! Really helpful.
This is what my revised code looks like.
def task(num):
num = int(num)
lst = []
if num < 2:
return lst
if num >= 2:
lst.append(2)
for i in range(3, num + 1):
if i % 2 == 1:
switch = True
for n in range(3, int(i ** 0.5) + 1, 2):
if i % n == 0:
switch = False
break
if switch:
lst.append(i)
return lst
The main problem lies with your inner for loop :
With your code you will append the list with i each time you find a number in the primetestrange that is not a divisor of i.
You might want to use a boolean here to store the fact that you found a divisor of i, then only append it to the list if you didn't.
To answer your question, your list is empty because the primetestrange is always empty in your example :
int(3**0.5) + 1 = 3 and int(5**0.5) + 1 = 3
range(3,3,2) = []
The array is empty because the range function will not include the upper limit, and since the inner loop is not doing what it should be expected to do in your code, the result will be an empty list until the parameter of the task function is superior or equal to 9
Your code gets it wrong on several counts, tell me if you understand why the following works?
def task(num):
num = int(num)
lst = [2]
if num < 3:
return lst
for i in range(3, num + 1):
if i % 2 == 1:
for n in range(3, int(i ** 0.5) + 1, 2):
if i % n == 0:
break
else:
lst.append(i)
return lst
(note: the for else clause is quite natural here, for else clauses are used when you search for something in a loop, you break when you find that something, if not break is encountered and the regular stopIteration is used to exit the loop the else part is performed, I say it is natural here since in pseudo code you would say something like "if my number can be divided by another number less than its square it is not prime, otherwise add it to the list of primes" see http://book.pythontips.com/en/latest/for_-_else.html for more detauls)
Its by no means a fast way to do it but I tried to stay as close to the spirit of your attempt while improving the aesthetics of the code
you can find prime numbers and the most dividable one in a dateset.`
a=[ int(x) for x in input("Enter 10 values: ").split() ]
c=[]
prime=[]
b=max(a)
for num in range(1,b+1):
for i in range(2,num):
if (num%i)==0:
break
else:
prime.append(num)
for i in a:
for j in prime:
if i%j==0:
c.append(i)
from collections import Counter
e=Counter(c)
f=e.most_common(1)
f
def prim(z):
lst = []
for i in range(2, z+1):
for j in range(2,i):
if i % j == 0:
break
else:
lst = lst + [i]
return lst
print(prim(20))
result:
[2, 3, 5, 7, 11, 13, 17, 19]