0
votes

So I recreated the sieve of eratosthenes but the result (prime numbers) is not output as i expected.

The first function is the sieve which returns a dictionary with all integers up to a given range as keys and True or False as their values (prime or not). The generator afterwards is supposed to get all the keys with a value of True (prime numbers). I think the problem is that I haven't used the generator correctly (I just learnt about generators), but I can't spot the mistake.

from math import sqrt

def sieve(x):
    values = {}
    for l in range(2, x + 1):
        values[l] = True
    for k in range(2, int(sqrt(x)) + 1):
        if values[k] == True:
            for j in range(k**2, x + 1, k):
                values[j] = False
    return values

def primes(dict1):
    for l in dict1:
        if l == True:
            yield list(dict1.keys())[l]

for k in primes(sieve(int(input()))):
    print(k, end = " ")

I expect all prime numbers (keys in the dictionary with a value of True) to be printed. But there is no output whatsoever.

3
Does any of the answers solves your problem? If they do then mark the answer accepted. Since you seem to be new to Stack Overflow, you should read What should I do when someone answers my question? - Sheldore

3 Answers

0
votes

Here is the corrected version where you directly access the dictionary keys and values by iterating over them using items(). I have done some changes to the code:

  • Store the user input in a variable called number

  • Directly access the keys and the values by iterating over dict1.items()

  • The point 2 simplifies the expression of yield in your original code.

  • if l == True: can be simply replaced by if value:


from math import sqrt

def sieve(x):
    # function body here 

def primes(dict1):
    for key, value in dict1.items(): # <--- Directly access keys and values
        if value:
            yield key
number = int(input())

for k in primes(sieve(number)):
    print(k, end = " ")

# 15
# 2 3 5 7 11 13 
0
votes

Iterating over a dictionary with for l in dict1 yields the keys, not the values.

Therefore if l == True is never true.

0
votes

for l in dict1 iterates over the keys of the dictionary, and the comparison if l==True expects a value. You can fix that, for example, by iterating over both keys and values using items:

for n, isprime in dict1.items():
    if isprime:
        yield n

A couple of unrelated notes:

  • you probably want to use a list (or even an array) of Booleans to store sieve data. Using a dict whose keys are consecutive numbers is wasteful.

  • when testing a Boolean value, use if x rather than if x == True. The latter will give incorrect answer for truthy values other than True, such as 1 or a non-empty container. (To test whether x is false, use if not x.)