2012-08-01 5 views
2

나는이의 출력으로 나오는 이유를 알아낼 수 없습니다 해요 :파이썬 생성기가 반복 반복을 반환합니까?

내 머리에 너무 많은 의미가
> File "<pyshell#177>", line 6, in func 
>  list.append(next(PrimeGen)) 
> StopIteration 

! 어쨌든 기본적으로 ifprime 함수와 생성기를 사용하여 Prime Generator를 만들어 목록에 소수를 수집하려고합니다.

이렇게하면 프라임인지 여부를 결정하고, 그렇지 않으면 값을 반환합니다.

def prime(x): 
    if (2**(x-1))%x ==1: 
     return x 

이 X까지 소수의 전체 목록을 반환해야 발전기를 만드는 대신 위의 오류를 제공합니다. 그것은 '아무튼 왜

def func(x): 
    count=0 
    list=[2] 
    PrimeGen = (prime(X) for X in range(3,x+1)) 
    while count<99: 
     list.append(next(PrimeGen)) 
     count+=1 
    print list 

아무도 설명 할 수 위의 함수 프라임 (X)는 소수로 (2)를 고려하지 않는 (그래서 범위는 3에서 시작할 것) 때문에 나는 그 내부에 2 목록 시작 일하니? 미리 감사드립니다. V.

+0

관련 : [Python에서 N 이하의 모든 소수를 나열하는 가장 빠른 방법] (http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python) – jfs

답변

3

주 당신의 주요 테스트

def prime(x): 
    if (2**(x-1))%x ==1: 
     return x 

는 예를 들면 선언, 잘못 341 = 11*312047 = 23*89 소수. 매우 큰 중간 값을 생성 x 큰에도

, 훨씬 더 효율적인 중간 값을 감소

pow(2,x-1,x) 

이다.

강한 소수성 검사의 적당히 효율적인 구현이 조금 더 멋지다

# The primes below 200 used as bases for the strong Fermat test, 
# prime bases have more discriminatory power than composite bases, 
# therefore we use prime bases first 
bases = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199] 

# The strong Fermat test for base b, where n is odd and large, 
# n - 1 = m * 2^s with odd m 
# the strong test checks whether b**m % n == 1 or 
# b**(2**j) % n == n-1 for a 0 <= j < s 
# If the test returns False, n is definitely composite, otherwise probably prime 
def strongFermat(b,n,m,s): 
    a = pow(b,m,n) 
    if a == 1: 
     return True 
    n1 = n-1 
    for i in xrange(s): 
     if a == n1: 
      return True 
     a = (a*a) % n 
    return False 

# Multiple strong Fermat tests, by default use 10 bases 
# The probability that a composite passes is less than 0.25**iters 
def sppTest(n, iters = 10): 
    # Assumes n > 1 and with no prime divisors < 200 
    m = n-1 
    s = 0 
    while (m & 1) == 0: 
     m >>= 1 
     s += 1 
    pbases = iters if iters < 47 else 46 
    for i in xrange(pbases): 
     if not strongFermat(bases[i],n,m,s): 
      return False 
    if pbases < iters: 
     for i in xrange(iters-pbases): 
      if not strongFermat(211 + 2*i,n,m,s): 
       return False 
    return True 

# Trial division to weed out most composites fast 
def trialDivisionPrime(n): 
    if n < 2: 
     return 0  # Not a prime 
    if n < 4: 
     return 2  # definitely prime 
    if n % 2 == 0 or n % 3 == 0: 
     return 0  # definitely composite 
    for d in xrange(5, 200, 6): 
     if d*d > n: 
      return 2 # definitely prime 
     if n % d == 0 or n % (d+2) == 0: 
      return 0 # composite 
    return 1   # not yet decided 

# The prime test, first do trial division by numbers < 200, 
# if that doesn't decide the matter, use some strong Fermat tests 
# using 20 tests is the paranoid setting for largish numbers, 
# for numbers in 64-bit range, ten or fewer suffice 
def prime(n): 
    td = trialDivisionPrime(n) 
    return td > 1 or (td == 1 and sppTest(n,20)) 

# just check a couple of larger numbers 
for c in xrange(100000): 
    if prime(c + 10**25): 
     print c 
+0

아, 그 이상한, 나는 방탄이라고 생각한 페르마의 작은 정리를 사용했는데 ... 파이썬에 잘못 번역 했나요? 더 효율적인 것을 주셔서 감사합니다. –

+3

번역은 정확하지만, 정리는 소수라는 것에 대해 _necessary_ 조건만을 기술합니다. 테스트 된 속성을 가진 복합 정수를 "Fermat pseudoprimes"라고합니다. 훨씬 더 빠른 확률 론적 테스트가 있지만, 알려진 최종 프라임 테스트는 여전히 상당히 느립니다. 더 많은베이스를 사용하여 더 높은 정확도를 얻을 수 있습니다. 강력한 페르마 테스트로 전환하는 것이 좋습니다. 더 강력하고 복잡하지 않습니다. –

5

99 미만의 값이 생성되었습니다. 루프 대신 itertools.islice()을 사용하십시오.

1

는 (그것은 종류의 바보는 달리 소수의 또는 None 경우 "주요"함수 반환 숫자 중 하나를 갖고있는 것 같아요 실제로 아래에 의한 방법 bool(None) == False을에 약간 수정 된 버전 대신에 잘 작동 것) 당신이 StopIteration 점점 발생하지 않습니다 불구하고 :

def isprime(x): 
    return (2**(x-1))%x==1 

def func(x): 
    list=[2] 
    list.extend(X for X in range(3,x+1) if isprime(X)) 
    print list 

을 다니엘 피셔, 당신을 언급 무엇으로가는 어쨌든 r 프라임 함수가 올바르지 않습니다.

관련 문제