Project Euler 357 prime number generator in Python 3
The most obvious improvement is to notice that if i in the_primes and if val not in the_primes both take \$\mathcal{O}(n)\$ time. If you made the_primes a set instead of a list it would only be \$\mathcal{O}(1)\$. So just write:

the_primes = set(primes())


Also note that your "prime number generator" is not actually a Python generator. For that you would need to add a yield:

def primes(ubound=10**5):
    """ Generating prime numbers https://stackoverflow.com/a/8627193/1770460 """
    size = (ubound - 3) // 2
    a = [False] * size
    s = 0
    while s &lt; size:
        t = 2 * s
        p = t + 3
        yield p
        for n in range(t * (s + 3) + 3, size, p):
            a[n] = True
        s = s + 1
        while s &lt; size and a[s]:
            s = s + 1


The set() call will then consume the generator. This will not make your code run faster, though (it needs about the same CPU) It might save you some memory, because you don't need the conversion from the internal list to the external set.



Your original code takes about 43.5s on my machine. With the two changes in this post this drops down to less than 1.7s:

$ python3 -m cProfile 357.py
275
time elapsed 1.6228196620941162 sec.
         583585 function calls in 1.623 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   ...
     9592    0.011    0.000    0.011    0.000 euler_357.py:14(primes)
        1    0.001    0.001    1.623    1.623 euler_357.py:3(&lt;module&gt;)
        1    1.524    1.524    1.584    1.584 euler_357.py:34(number_divisors)
        1    0.026    0.026    0.026    0.026 euler_357.py:56(find_count)
   ...