我的 Python 函数中有一个生成器;我如何 return 修改列表?
I have a generator in my Python function; how can I return a modified list?
一点背景知识:我一直在尝试编写 "Sieve of Eratosthenes" 算法。应 Whosebug Python 聊天室一些优秀(且非常耐心)程序员的要求,我阅读了 enumerate()
函数并找到了一种将其合并到我的代码中的方法(是的,我在这里非常新手)。到目前为止,我的(可行;returns 预期响应)代码如下所示:
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
我也试过将列表 numbers
中的所有 True
元素附加到初始化列表 primes
,但没有成功。
非常欢迎任何提示或建议。
这与 enumerate
您正在尝试 return 生成器中的某些内容无关 python 3.3 之前是非法的,并且 from 3.3+ it means something entirely different.
如果您可以使用它而无需返回列表,我建议您将函数保留为生成器,如果您想要列表结果,则只需在 return 值上调用 list()
:
primes = list(SieveErat(150000)) #this replaces loop with .append
但是要理解哪里出了问题,如果你的函数中仍然有 yield
语句,那么它必须 return 一个生成器对象,如果你不希望它 return 生成器对象然后一起删除 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
然而,这将 return True
和 False
的列表,而不是 True 的数字,您可以保存一个单独的列表,其中包含所有素数和 .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
。
一点背景知识:我一直在尝试编写 "Sieve of Eratosthenes" 算法。应 Whosebug Python 聊天室一些优秀(且非常耐心)程序员的要求,我阅读了 enumerate()
函数并找到了一种将其合并到我的代码中的方法(是的,我在这里非常新手)。到目前为止,我的(可行;returns 预期响应)代码如下所示:
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
我也试过将列表 numbers
中的所有 True
元素附加到初始化列表 primes
,但没有成功。
非常欢迎任何提示或建议。
这与 enumerate
您正在尝试 return 生成器中的某些内容无关 python 3.3 之前是非法的,并且 from 3.3+ it means something entirely different.
如果您可以使用它而无需返回列表,我建议您将函数保留为生成器,如果您想要列表结果,则只需在 return 值上调用 list()
:
primes = list(SieveErat(150000)) #this replaces loop with .append
但是要理解哪里出了问题,如果你的函数中仍然有 yield
语句,那么它必须 return 一个生成器对象,如果你不希望它 return 生成器对象然后一起删除 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
然而,这将 return True
和 False
的列表,而不是 True 的数字,您可以保存一个单独的列表,其中包含所有素数和 .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
。