0

This is what I have:

list1 = range(2, 11)
list2 = range(2, 11)
primes = []
primes.append(?)
? % ? == 0....
primes = set(primes)

Using comprehensions, how can I have list1 be iterated 2-10, and divided by an iterated list2 and have the results with no zero remainder appended to primes? I can then turn the list into a set to remove duplicates. I see that a function is possible as well, I just can't get my brain around to how to write it?

The desired result is. primes = [2, 3, 5, 7]

  • Can you give an example of the desired output? – Elliot Roberts Sep 29 '17 at 17:48
  • If you want list1 to contain 1-10 why did you define it with `range(0, 11)`? – PM 2Ring Sep 29 '17 at 17:50
  • I'm learning Python 3. – Jorge Gandara Sep 29 '17 at 17:51
  • FWIW, there's some great prime code at https://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n especially in the answer by Robert William Hanks. Unfortunately, that's an old page, so the code is for Python 2, but there's a Python 3 version of RWH's pure Python solution [here](https://stackoverflow.com/a/38743446/4014959). – PM 2Ring Sep 29 '17 at 18:01

3 Answers3

3

Here's a compact way to do the loops that you ask for. Your lists should not contain 1, though.

>>> list1 = list(range(2,11))
>>> list2 = list(range(2,11))
>>> primes = [a for a in list1 if all((a % b) != 0 for b in list2 if a != b) ]
>>> primes
[2, 3, 5, 7]

There are no duplicates in the results, because the comprehension just collects elements of list1. But there are plenty of ways to improve prime number detection, of course. This just shows you how to apply comprehensions to your algorithm.

alexis
  • 43,587
  • 14
  • 86
  • 141
  • Remember you only need to check up to sqrt(i) (Sieve of Erastothenes): `primes = [a for a in range(2,10) if all((a % b) != 0 for b in range(2,int(math.floor(math.sqrt(a)))) if a != b) ]` – cowbert Sep 29 '17 at 18:05
  • 1
    Oh there's about a billion ways prime checking can be improved, but that was not the question. (Why even start with two lists and not one?) – alexis Sep 29 '17 at 18:06
  • 1
    PS @cowbert, since `b < sqrt(a)` you don't need to check `if a != b` ;-) – alexis Sep 29 '17 at 18:11
  • 1
    I blame copypasta for that one :) – cowbert Sep 29 '17 at 18:13
0

Try this (change 10 by the number you want)

primes = []
for number in range(1,10):
    is_prime = True
    for div in range(2, number-1):
        if number % div == 0:
            is_prime = False
            break
    if is_prime:
        primes.append(number)

Be careful though, this is not efficient at all. A little improvment is to change (number - 1) by int(sqrt(number)). But that's math rules. If you want the first 1000000 primes, that won't work. You wanna perhaps check more advanced methods to find primes if you need more.

Explanation: you iterate first with all numbers between 1 and 10 - 1 = 9. This number is store into the variable "number". Then you iterate other the possible dividers. If the modulo for each pair of number and divider is 0, then it is not a prime number, you can mark it as not prime (is_prime = False) then quit your loop. At the end of the inner loop, you check the boolean is_prime and then add to the list if the boolean is set at True.

Adrien Logut
  • 754
  • 4
  • 12
0

Here's a reasonably efficient way to find primes with a list comprehension, although it's not as efficient as the code by Robert William Hanks that I linked in the comments.

We treat 2 as a special case so we don't need to bother with any higher even numbers. And we only need to check factors less than the square root of the number we're testing.

from math import floor, sqrt

primes = [2] + [i for i in range(3, 100, 2) 
    if all(i % j != 0 for j in range(3, 1 + floor(sqrt(i)), 2))]
print(primes)

output

[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]

Here's an alternative (less efficient) version that iterates over your list1 (which isn't really a list, it's a range object).

list1 = range(2, 100)
primes = [i for i in list1 if not [j for j in list1 if j*j <= i and i % j == 0]]
print(primes)
PM 2Ring
  • 50,023
  • 5
  • 64
  • 150