Нет ничего плохого в StopIteration
, действительно, это ожидаемое поведение для генераторов.
Я бы сказал, что эта реализация более питонна (не обязательно более эффективна):
def get_primes(n):
"""Generates prime numbers < n"""
return (x for x in xrange(2,n) if all(x % i for i in xrange(2,x)))
Pythonic для меня означает ясный, лаконичный, читаемый и использующий сильные стороны языка. Хотя я вижу, что ваша реализация - это своего рода сито, я знаю это только из предыдущего опыта работы с такими алгоритмами. Реализацию выше я могу прочитать непосредственно как прямой тест делимости.
Примечание: есть небольшое отличие в интерфейсе, ваша реализация выдает простые числа <= n, тогда как моя реализация выдает простые числа <n. Очевидно, что это можно легко и тривиально изменить (просто измените n на n + 1 в теле функции), но я чувствую, что более питонно генерировать простые числа вплоть до, но не включая n, чтобы быть более совместимым с тем, как, скажем, <code>range() встроенные работы.
РЕДАКТИРОВАТЬ: ТОЛЬКО ДЛЯ УДОВОЛЬСТВИЯ
Вот минимум питонная реализация, и, вероятно, тоже довольно неэффективная :)
def get_primes(n):
import re
return (x for x in xrange(2,n) if re.match(r'^1?$|^(11+?)\1+$', '1' * x) is None)
Я называю это наименее питоническим, потому что вы бы несколько дней чесали голову, чтобы понять, как это работает, если вы раньше не видели этот трюк !!