2016-07-12 7 views
0

少しの背景:私は "Sieve of Eratosthenes"アルゴリズムをコーディングしようとしていました。 StackOverflow Pythonのchatroom上のいくつかの上級者(そして非常に患者さん)の要望で、私はenumerate()関数を読んで、それを私のコードに組み込む方法を見つけました(はい、私は非常に初心者です)。これまでのところ、私の(実行可能な、リターンが期待レスポンス)コード次のようになります。言いたいことが私はPython関数の中にジェネレータを持っています。変更されたリストを返すにはどうしたらいいですか?

def SieveErat(n): 
    numbers = [False]*2+[True]*(n-1) 

    for index, prime_candidate in enumerate(numbers): 
     if prime_candidate == True: 
      yield index 
      for x in xrange(index*index, n, index): 
       numbers[x] = False 

primes = [] 

for x in SieveErat(150000): 
    primes.append(x) 

print primes[10002] 

言うまでもなく、enumerate()機能はそれほど厄介な私が前に持っていたものは何でもネストされたループよりも、この多くをコーディングます。しかし、私は関数に添付を含めることによって、このコードを短縮しようとしたとき、私はエラー - すなわち取得保管ので、私はまた、追加しようとした私は

File "SievErat.py", line 13 
     return numbers 
SyntaxError: 'return' with argument inside generator 

、何かについてenumerate()を理解していないよということを恐れますすべてTrueのリストの中にnumbers初期化されたリストprimesに、しかし運が見つかりませんでした。

ヒントやアドバイスは大歓迎です。

+0

um ...あなたのコードには「戻り値」はありません。あなたが直面しているエラーを引き起こすコードを表示してください。 –

+0

をpythonで3.3より前のものにすると、 'return 'と 'yield'を同じ関数で使うことはできません。python 3.3+では、ジェネレータコンテキストでは全く別のものを意味します(http://stackoverflow.com/questions/16780002/)。 return-in-generator-with-python-3-3) –

答えて

1

これはあなたのpython 3.3の前に違法である発電機で何かを返すようにしよう、とfrom 3.3+ it means something entirely different.

enumerateとは何の関係もありません、私はあなたが必要とすることなく、それを使用する可能性がある場合、あなたのファンクションジェネレータを残してお勧めしますリスト背中、そしてあなたは、リストの結果を望むならば、単に戻り値にlist()を呼び出します。それはジェネレータオブジェクトを返す必要があり

primes = list(SieveErat(150000)) #this replaces loop with .append 

しかし、あなたの機能はまだそれにyield文を持っている場合、何が悪かったのかを理解すること、もしあなたがそれをやり直すことを望まないならRNジェネレータオブジェクトは、すべて一緒にyield文を削除します。

def SieveErat(n): 
    numbers = [False]*2+[True]*(n-1) 

    for index, prime_candidate in enumerate(numbers): 
     if prime_candidate == True: 
      #yield index #no yield statement if you want to return the numbers list 
      for x in xrange(index*index, n, index): 
       numbers[x] = False 

    return numbers #return at end 

は、しかし、これは、その後True、代わりに真のある数字のFalseのリストを返します、あなたの代わりにすべての素数を持つ別のリストを保持することができますそしてそれに.appendは毎回あなたはyield何かでしょう:

def SieveErat(n): 
    numbers = [False]*2+[True]*(n-1) 
    result = [] #start with no results 
    for index, prime_candidate in enumerate(numbers): 
     if prime_candidate == True: 
      results.append(index) #instead of yield index 
      for x in xrange(index*index, n, index): 
       numbers[x] = False 
    return results 

しかし、これは発電機から一歩後退のように感じているが、個人的に私はちょうどあなたが投稿してlistに結果をキャストしているものを維持するだろう。

+0

あなたの有益な応答をありがとう、Tadhg-私はあなたの応答をupvotedしました。あなたが気にしないなら、なぜあなたがあなたの例で示したように、 'append'の代わりに' yield 'を取り除くように感じるのかを拡大して、後退のように感じることができますか? – daOnlyBG

+1

@daOnlyBG(公式のpython wiki(https://wiki.python.org/moin/Generators)のような)ジェネレータで見た参考文献のほとんどは、リストの作成からジェネレータの作成、見積もりの​​変更そのリンクの一部ですが、それはメモリ内の完全なリストを構築します。これは明らかに許容できません。なぜなら、n個の "10メガバイト"の整数をすべてメモリに保持する余裕がないからです。 "" _ –

+0

簡潔で有益な応答をお寄せいただきありがとうございます! – daOnlyBG

関連する問題