Генерация простых чисел с помощью протокола Iterator

Я пытаюсь получить серию простых чисел от 1 до n. Вместо использования диапазона и цикла я пытаюсь реализовать его с помощью протокола итератора. Пока у меня есть нижеприведенное, но, как вы увидите, это не то, что я ожидал.

class Prime:
    def __init__(self, n):
        self.n = n
        self.current = 1
    def __iter__(self):
        return self
    def __next__(self):
        x = self.current
        self.current += 1
        for num in range(self.current, self.n):
            if num > 1:
                for i in range(2, num):
                    if num % i == 0:
                        break
                else:
                    return num


d = Prime(20)
c = iter(d)
print(next(c))
print(next(c))
print(next(c))
print(next(c))
print(next(c))
print(next(c))

он печатает 2,3,5,5,7,7 И цель - напечатать 2,3,5,7,11...19

Я просто не хочу ответа, пожалуйста, объясните, как, я был бы признателен. Благодарность

2 ответа

Решение

Когда ты звонишь next в том случае, если вы увеличиваете currentтак что вы можете начать с того места, где остановились. Затем вы переходите к поиску следующего простого числа, но не обновляетеcurrent. Вы можете увидеть, что происходит, если распечатаетеcurrent при каждом следующем звонке.

print(f'current:{c.current} | next prime: {next(c)}')
print(f'current:{c.current} | next prime: {next(c)}')    
print(f'current:{c.current} | next prime: {next(c)}')
print(f'current:{c.current} | next prime: {next(c)}')
print(f'current:{c.current} | next prime: {next(c)}')    # current:5 | next prime: 7
print(f'current:{c.current} | next prime: {next(c)}')    # current:6 | next prime: 7
print(f'current:{c.current} | next prime: {next(c)}')    # current:7 | next prime: 11
print(f'current:{c.current} | next prime: {next(c)}')    # current:8 | next prime: 11
print(f'current:{c.current} | next prime: {next(c)}')

...

Например, если current пять, то следующее простое число - семь. currentувеличивается до шести, затем находит следующее простое число, которое также равно семи.

Удалите оператор, увеличивающий current. Затем добавьте заявление для обновления currentкогда будет найдено следующее простое число.

...
    def __next__(self):
        x = self.current
##        self.current += 1
        for num in range(self.current, self.n):
            if num > 1:
                for i in range(2, num):
                    if num % i == 0:
                        break
                else:
                    self.current = num + 1 
                    return num

  • Распечатка соответствующих данных / сравнений /... может быть полезным инструментом.
  • Также может быть полезно прохождение кода карандашом и бумагой - будь переводчиком
  • Если вы используете среду IDE, изучение ее возможностей отладки должно быть в списке приоритетов.

Попробуй это

class Prime:
    def __init__(self, n):
        self.n = n
        self.current = 2
    def __iter__(self):
        for i in range(self.current, self.n+1):
            pflag = True
            for j in range(2, i):
                if i%j == 0:
                    pflag=False
                    break
                    
            if pflag:
                self.current=i
                yield i
d = Prime(20)
c = iter(d)
print(next(c))
print(next(c))
print(next(c))
print(next(c))
print(next(c))
print(next(c))
print(next(c))
Другие вопросы по тегам