我的Python函数中有一个生成器;如何返回修改后的列表?

时间:2016-07-12 00:39:48

标签: python algorithm function generator enumerate

一点背景:我一直试图编写一个" Eratosthenes的筛子"算法。应StackOverflow Python聊天室的一些优秀(非常耐心)程序员的要求,我对enumerate()函数进行了一些阅读,并找到了将其合并到我的代码中的方法(是的,我非常感谢这里的新手)。到目前为止,我的(可行的;返回预期的响应)代码如下所示:

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()的某些内容,因为当我试图通过在函数中包含附加内容来缩短此代码时,我不断收到错误 - 即,

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

我还尝试将列表True中的所有numbers元素附加到初始化列表primes,但没有找到运气。

任何提示或建议都会受到欢迎。

1 个答案:

答案 0 :(得分:1)

这与enumerate无关,你试图在生成器中返回某些东西,而python 3.3是非法的,from 3.3+ it means something entirely different.

如果您可以在不需要列表的情况下使用它,我建议您将函数保留为生成器,如果您想要列表结果,则只需在返回值上调用list()

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

但是为了理解出了什么问题,如果你的函数仍然有yield语句,那么它必须返回一个生成器对象,如果你不希望它返回一个生成器对象然后删除{ {1}}一起声明:

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的列表而不是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