1

I'm trying to get the sum of all the prime numbers below 2,000,000 in Python, using a lambda function. (I've bruteforced it, but that takes much too long, and I want a better solution.) Here is what I have so far:

def isPrime(n):
    for x in range(2, int(n**0.5)+1):
        if n%x==0: return False
    return True


print reduce(lambda x: isPrime(x), [range(200)])

Now, this just prints numbers incrementing from 1 to 200, so I don't think reduce is working =\

Anyone have any tips?

Andrew Jaffe
  • 23,727
  • 2
  • 45
  • 55
Tetramputechture
  • 2,791
  • 2
  • 25
  • 45

2 Answers2

2

There are a few odd things going on with your code.

  • I think you actually want to be using filter(), not reduce().
  • lambda x: isPrime(x) is equivalent to isPrime (after all, isPrime is already a function that returns the result of isPrime).
  • [range(200)] creates a nested list. The only element in the outer list is a list with the numbers from 0 to 200. I think you just want the single list.

So, try the following:

print filter(isPrime, range(200))
Andrew Clark
  • 180,281
  • 26
  • 249
  • 286
  • Is there any way I can increment the values by 2 so I can have it more efficient? I'm using sum(filter(isPrime, range(2000000))) and I need this to be faster than the brute force method. – Tetramputechture Mar 14 '13 at 22:49
  • 1
    Your isPrime function is the brute force part of the method. Improving it will make much larger improvements in performance than any optimization of the summation of the elements. – Tyler Bindon Mar 14 '13 at 22:53
  • 1
    @Tetramputechture Use `range(1, 200, 2)` to increment by 2, but Tyler is right, your focus should be on a better prime testing function. [This answer should help](http://stackoverflow.com/a/2068548/505154). – Andrew Clark Mar 14 '13 at 23:01
2

There are lots of things wrong here. The first is that you can replace lambda x: isPrime(x) with simply isPrime. Functions are first class in Python, which means you can just pass them around in the same way as integers or strings. The second is that you are passing a list of lists; [range(200)] is a list containing the return value of range(200) range returns a list so you are only reducing a single value. This gets around the third problem, which is that your reduce function should accept 2 arguments, as reduce calls the function passed on pairs of items as a time. As it is, there is only one item so the function is called 0 times and the first item on list is returned.

What I suspect you want to do is to filter the list, you can use the filter function to do this or you can use a list comprehension which would look like this:

[x for x in range(200) if isPrime(x)]
Steve
  • 1,167
  • 5
  • 11
  • 1
    It shows :P In answer to your increment by 2 question try `help(range)` in the Python command line. – Steve Mar 14 '13 at 22:53
  • just oneeee more thing :) why does it print 15 when I type print sum([x for x in range(1, 10, 2) if isPrime(x)]) – Tetramputechture Mar 14 '13 at 22:58
  • Don't forget to add the 2 back. 2 is prime and you skip it with range(1, 10, 2). Plus it's probably better to start with 3. The primality of 1 is not an easy question to answer. ie: range(3, 10, 2) – Tyler Bindon Mar 14 '13 at 23:12