2016-07-12 2 views
0

Немного фона: Я пытался закодировать алгоритм «Решетка Эратосфена». По просьбе некоторых тонких (и очень терпеливых) программистов в чат-комнате StackOverflow Python я прочитал некоторую информацию о функции 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() делает кодирование это гораздо, гораздо менее громоздкими, чем бы то ни были вложенные циклы у меня было раньше. Тем не менее, я боюсь, что я не понимая, что-то о enumerate(), потому что, когда я попытался сократить этот код, включив в эту директиву функции, я продолжал получать errors- именно

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

Я также попытался добавления все True элементов в списке numbers в инициализированный список primes, но не нашел удачи.

Любые советы и советы были бы очень приветствуемыми.

+0

um ... ваш код не содержит никаких «возвратных номеров», пожалуйста, покажите нам код, который вызывает ошибку, с которой вы сталкиваетесь. –

+0

в python до 3.3 вы не можете «возвращать », а также 'yield' в той же функции, в python 3.3+ [return означает нечто совершенно иное в контексте генератора] (http://stackoverflow.com/questions/16780002/ return-in-generator-together-with-yield-in-python-3-3) –

ответ

1

Это не имеет ничего общего с enumerate вы пытаетесь вернуть что-то в генераторе, который, прежде чем питона 3,3 является незаконным, и from 3.3+ it means something entirely different.

Я рекомендую вам оставить функцию генератора, если вы можете использовать его без необходимости список назад, и если вы хотите получить результаты списка, то просто позвоните list() на возвращаемом значении:

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

Но чтобы понять, что пошло не так, если ваша функция все еще имеет yield заявления, в нем, то он должен вернуть объект генератора , если вы не хотите, чтобы он возвращался гп объект генератора затем снимите 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- я подтвердил ваш ответ. Если вы не возражаете, не могли бы вы рассказать о том, почему вы хотите избавиться от «урожая» вместо «append» (как вы показали в вашем примере), похоже на шаг назад? – daOnlyBG

+1

@daOnlyBG Большинство ссылок, которые я видел на генераторах (например, [официальный python wiki] (https://wiki.python.org/moin/Generators)) работают над изменением от создания списка до создания генератора, чтобы процитировать часть этой ссылки _ "", но она строит полный список в памяти. Это явно неприемлемо в нашем случае, потому что мы не можем позволить себе хранить все n "10 мегабайт" целых чисел в памяти. "" –

+0

Еще раз спасибо за краткий, но неинформативный ответ! – daOnlyBG

Смежные вопросы