So I'm trying to print all the prime numbers up to 100. Here's my code so far:
primes = []
for num in range(100):
if num > 1:
for i in range(2, num):
if num % i != 0:
primes += [num]
break
else:
break
print(primes)
However when i run the code, it only does the calculation (if num % i != 0) for the first iteration in the range (for i in range(2, num)). This is a problem in the case of numbers like 15, where the first iteration in for i in range is 2. 15 divided by 2 does not give a whole number, and so it runs primes += [num]. It has taken the first iteration and has not run the rest of them. Is there a way to run all the iterations in the range?
Try this:
primes = []
for num in range(100):
if num > 1:
for i in range(2, num):
if num % i == 0:
break
else:
primes.append(num)
print(primes)
The code will execute the else block only if the inner for loop is exhausted, i.e completes it's all iteration without breaking.
You got the logic somewhat wrong. Here's how you've to do it
primes = []
for num in range(2, 100): # 0 and 1 aren't primes
for i in range(2, num):
if num % i == 0:
break
else: # the else condition is for the for loop i.e. if it executes without break
primes.append(num)
print(primes)
The all function may be what you're looking for!
Here is my take on it.
>>> def primes(limit=100):
... for number in range(limit):
... is_prime = all([number % divisor != 0 for divisor in range(2, number)])
... if is_prime:
... yield number
...
>>> list(primes(10))
[0, 1, 2, 3, 5, 7]
>>> list(primes(100))
[0, 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
>>>
Is not complete, 0 and 1 are not primes. But I think you get the idea.
tried to adapt to your approach although, I think there should be better ways to solve this problem
>>> primes = []
>>> for num in range(2,100):
... p = True
... for i in range(2, num):
... if num % i == 0:
... p = False
... if p:
... primes += [num]
...
>>> primes
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
Related
I want to create a python function that accepts two integer parameters finds all prime numbers between them and returns these primes in a list.
I did a part of the code but I'm stuck in printing prime numbers and turning them into a list.
a,n = map(int,input("Enter a and n: ").split())
def isPrime(a,n):
if n <= 1:
return False
for i in range(a, n+1):
if n % i == 0:
return False;
return True
You can make your is_prime function shorter like that:
a,n = map(int,input("Enter a and n: ").split(" "))
def is_prime(a):
return all(a % i for i in range(2, a))
out = []
for i in range(a, n):
if is_prime(i):
out.append(i)
print(out)
The output for a = 0 and n = 90 would be:
[0, 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89]
I edited your solution so that you only check for numbers with a value of 2 or higher. Your solution allows negatives, which is not correct.
Also, your clause for checking for the primes is wrong, as you check if n has divisors. Instead, you want to check if every number in [a, n) interval has a divisor. The interval is [a, n) because a prime number has only 1 and itself as divisors.
My code does just that, so if the algorithm finds that a number in the [a, n) interval has no divisors, then it will append it in an empty list that I created before going through the loop, and return the list, then print it.
a, n = map(int, input("Enter a and n: ").split())
def isPrime(a, n):
lst = []
for i in range(a, n + 1):
if (i > 1):
for j in range(2, i):
if (i % j == 0):
break
else:
lst.append(i)
return lst
print(isPrime(a, n))
My output for a = 0 and n = 100 is:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
My code is a modified version of this.
So I have a list of numbers that look like "3723311723" and "13617172343". As you can see these numbers can be split into prime numbers e.g "3723311723" could be split into 37, 23, 31 ect. How could I write a python program that takes a number like this as an input and returns a list of the primes inside it (in the order they are found)?
Thanks.
If you know that the numbers are definitely gonna be prime, then you just have to break up the string into substrings of length 2, right?
s = "37233141712331719337"
print([int(s[i:i+2]) for i in range(0, len(s), 2)])
Output:
[37, 23, 31, 41, 71, 23, 31, 71, 93, 37]
EDIT:
This does a recursive search to find non-overlapping primes. If there's no valid split, it returns False. The usual caveats of recursion apply: if the input is too long, you'll recurse too deep and the program will blow up. But you can use a stack instead of recursing if that's an issue.
def is_prime(n):
for k in range(2, n):
if n % k == 0:
return False
return True
def primesplit(s, i=0):
if i+1 >= len(s):
return []
if i+2 <= len(s):
two_digits = int(s[i:i+2])
if is_prime(two_digits):
remaining_digits = primesplit(s, i+2)
if isinstance(remaining_digits, list):
return [two_digits] + remaining_digits
one_digit = int(s[i:i+1])
if not is_prime(one_digit):
return False
remaining_digits = primesplit(s, i+1)
if isinstance(remaining_digits, list):
return [one_digit] + remaining_digits
return False
s = "37233141712331719337"
result = primesplit(s)
print(result)
print("".join(map(str, result)) == s)
Output:
[37, 23, 31, 41, 71, 23, 31, 7, 19, 3, 37]
True
It's a bit complicated what you are asking for, but here's what I thought you meant:
Given a number, look for any two digit prime within that number(I assume they ARE allowed to overlap)
A easy way to do that is like this:
def isPrime(number):
if number>1:
for i in range(2,number):
if (number%i)==0:
return False
return True
else:
return False
def getPrimes(number):
number=str(number)
retList=[]
for i in range(len(number)-1):
temp=int(number[i:i+2])
if isPrime(temp):
retList+=[temp]
return retList
This does NOT check for single digit primes, but that could easily be added if you needed it (simply check every digit in the original number if they are prime).
Is this what you wanted?
This is what you are looking for:
The loop finds both 1 and 2 digit prime numbers in the order they appear in the original number and there will be no duplicates too.
In [126]: n
Out[126]: '37233141712331719337'
In [127]: primes = []
...: for i in range(len(n)-1):
...: n1 = int(n[i])
...: n2 = int(n[i:i+2])
...: if isPrime(n1):
...: if n1 not in primes:
...: primes.append(n1)
...: if isPrime(n2):
...: if n2 not in primes:
...: primes.append(n2)
...:
In [128]: primes
Out[128]: [3, 37, 7, 2, 23, 31, 1, 41, 17, 71, 19]
Here is how you can use the isprime method from the sympy module, and zip:
from sympy import isprime
n = "37233141712331719337"
lst = [int(i + j) for i, j in zip(n, n[1:]) if isprime(int(i + j))]
print(lst)
Output:
[37, 23, 31, 41, 17, 71, 23, 31, 17, 71, 19, 37]
I want to iterate through a list in python, detect prime numbers and then add them to another list.
primes = []
nprimes = []
for j in range(0, len(arr)):
num = arr[j] #my list with numbers to check
if num > 1:
for k in range(2, num):
if (num % k) == 0:
nprimes.append(num)
break
else:
primes.append(num)
else:
print(num, " can't be checked, because its smaller than 1")
I have the problem that numbers are always added which are not prime numbers. Also in general the code does not seem to work properly.
If num % k == 0 is false you can't say it's prime directly you have to wait the whole loop, so move the else with the for loop, it'll be executed of no break has been encountered which means it's prime
you may iterate directly on the values for num in arr
you can stop your loop at sqrt(num) you won't find a new divisor after that
for num in arr:
if num > 1:
for k in range(2, int(num ** 0.5) + 1):
if num % k == 0:
nprimes.append(num)
break
else:
primes.append(num)
else:
print(num, " can't be checked, because its smaller than 1")
For learning purposes, let's play with a different approach. First, I recommend you move your trial division code into its own predicate function is_prime(), that returns True or False, so it can be optimized independently of the rest of your code.
Then, I'm going to have itertools.groupby divide the list into prime and non-prime sequences that we splice onto the appropriate lists:
def is_prime(number):
if number < 2:
return False
if number % 2 == 0:
return number == 2
for divisor in range(3, int(number ** 0.5) + 1, 2):
if number % divisor == 0:
return False
return True
if __name__ == "__main__":
from random import sample
from itertools import groupby
array = sample(range(1, 100), 15)
primes = []
composites = []
for are_prime, numbers in groupby(array, is_prime):
if are_prime:
primes.extend(numbers)
else:
composites.extend(numbers)
print("Numbers:", array)
print("Primes:", primes)
print("Composites:", composites)
OUTPUT
% python3 test.py
Numbers: [91, 87, 10, 2, 11, 24, 21, 12, 46, 61, 15, 32, 57, 22, 5]
Primes: [2, 11, 61, 5]
Composites: [91, 87, 10, 24, 21, 12, 46, 15, 32, 57, 22]
%
There are lots of ways to go about this problem, many of them educational!
There is a question on codewars, life without primes. I solved it yet the time issue comes up. I really cannot find a better way. The instructions go like;
Consider an array that has no prime numbers, and none of its elements has any prime digit. It would start with: [1,4,6,8,9,10,14,16,18,..]. The element at index 1 is 4.
There will be given an integer n and the task will be return the number at that index in the array. For example, solve(1) = 4, as explained above.
Here is my solution
def solve(n):
no_primes=[]
a=1
if n == 1:
return 4
else:
while True:
try:
no_primes[n]
break
except IndexError:
if is_prime(a) == True:
if is_num_prime(a) == False:
no_primes.append(a)
a=a+1
return no_primes[n]
def is_prime(num):
numbers = list(map(int, list(str(num))))
#primes=[0,2,3,5,7,9]
non_primes=[0,1,4,6,8,9]
return all(list(map(lambda x:x in non_primes,numbers)))
def is_num_prime(num):
if num == 2:
return True
elif num >2:
for i in range(2,num):
if num%i == 0:
return False
else:
return True
else:
return False
Getting rid of the while loop could help but I need to keep on appending until I can reach the value from the list. A recursive for loop with using range(1,n) where n increases recursively may be an option but I could not write it anyways.
You can easily break down this problem in simple steps:
Generate the all the combinations
You can make an endless generator making ever-longer combinations of these digits
def generate_numbers():
digits= '014689'
for i in itertools.count(1): # ever longer number
for x in itertools.product(digits, repeat=i): # combine the digits
number = ''.join(x)
if number[0] != '0':
yield int(number)
print(list(itertools.islice(generate_numbers(), 40)))
[1, 4, 6, 8, 9, 10, 11, 14, 16, 18, 19, 40, 41, 44, 46, 48, 49, 60, 61, 64, 66, 68, 69, 80, 81, 84, 86, 88, 89, 90, 91, 94, 96, 98, 99, 100, 101, 104, 106, 108]
Check whether a number is prime
def is_prime(num):
if num in {0, 1,}:
return False
if num == 2:
return True
if not (num % 2):
return False
for i in range(3, round(num **.5 + 1), 2):
if not (num % i):
return False
return True
return the nth non-prime number
def solve(n):
non_prime_solutions = (i for i in generate_numbers() if not is_prime(i))
return next(itertools.islice(non_prime_solutions, n, None))
[solve(i) for i in (1, 2, 10, 100)]
[4, 6, 44, 644]
Since all of this is lazily evaluated, this should go pretty fast. The one thing that can be optimised is the is_prime
import math
import itertools
def is_prime(n):
return all(n % i for i in range(2, int(math.sqrt(n) + 1)))
prime_digits = {"2", "3", "5", "7"}
def no_prime_digit(n):
return not any(x in prime_digits for x in str(n))
def non_primes():
return (i for i in itertools.count() if no_prime_digit(i) and not is_prime(i))
def get_non_prime(n):
return next(x for i, x in enumerate(non_primes()) if i == n - 1)
print([(x, get_non_prime(x)) for x in [1, 10, 100]])
I created a simple recursive function that determines whether a number is even or odd, performs math on them, and appends them to a list:
iter_list = []
def function(n):
iter_list.append(n)
if n < 2:
print iter_list
print iterations
pass
elif n % 2 == 0:
even = n / 2
iter_list.append(even)
collatz(even)
elif n % 2 == 1:
odd = (3 * n) + 1
iter_list.append(odd)
collatz(odd)
else:
print "Code not working."
pass
stdin = input("Number")
print collatz(stdin)
iterations = len(iter_list) - 1
When I run the function with 276, the output is:
Number[276, 138, 138, 69, 69, 208, 208, 104, 104, 52, 52, 26, 26, 13, 13, 40, 40, 20, 20, 10, 10, 5, 5, 16, 16, 8, 8, 4, 4, 2, 2, 1, 1]
Which is what I would expect, except that there are two instances of each number, instead of one.
How would I fix this?
Let's look at what happens when n == 4:
def function(n):
iter_list.append(n)
if n < 2:
print iter_list
print iterations
pass
elif n % 2 == 0:
even = n / 2
iter_list.append(even)
collatz(even)
...
On line 2, we append 4.
On line 9, we append 2.
We call collatz(2)
On line 2, we append 2.
On line 9, we append 1.
We call collatz(1)
Note that we added 2 twice! Perhaps you should only append to the list at the beginning of your function instead of additionally inside the conditionals.