【问题标题】:yield has a rare behaviouryield 具有罕见的行为
【发布时间】:2014-06-09 06:15:06
【问题描述】:

我正在尝试编写一个生成器,但发生了一些我不明白的事情:

我的代码片段:

def processTable(pathToTable, pages):

    #some code here to open PyTable, get node etc
    for i in pages:

        try:
            del aux10, aux11, aux20, aux21 
        except:
            pass


        aux10 = [row['value'] for row in tab.where('(done == 1) & (pageNr == i)')] 
        aux20 = [row['value'] for row in tab.where('(done == 2) & (pageNr == i)')] 
        aux11 = [row['value'] for row in tab.where('(done == 3) & (pageNr == i)')] 
        aux21 = [row['value'] for row in tab.where('(done == 4) & (pageNr == i)')]

        yield (i, np.array(aux10).mean(), np.array(aux10).std()), (i, np.array(aux11).mean(), np.array(aux11).std()), (i, np.array(aux20).mean(), np.array(aux20).std()), (i, np.array(aux21).mean(), np.array(aux21).std()) 

预期输出

预期的输出将是 4 个值,例如:

a = ((element10_i, its_mean, its_std), (element_i+1, its_mean, its_std), ...)

b = ((element11_i, its_mean, its_std), (element_i+1, its_mean, its_std), ...)

c = ((element20_i, its_mean, its_std), (element_i+1, its_mean, its_std), ...)

d = ((element21_i, its_mean, its_std), (element_i+1, its_mean, its_std), ...)

所以它起作用了。我确实喜欢这样:

>>import generatorTables as pro
>>from itertools import izip
>>testPages = [1,2,3,4,5,6,7,8]
>>gen = pro.processTable(pathToPyTable, testPages)
>>a,b,c,d = izip(*gen)

输出

>>a
((1, 9.034405600010885, 0.32797176526389787), (2, 9.0305521432119082, 0.33138509286206153), (3, 8.9994696778116783, 0.31336561331661922), (4, 9.0586203572673725, 0.31509917770176399), (5, 9.1253471514046396, 0.32446032765733307), (6, 8.9412112513166786, 0.31844521244534058), (7, 8.9666645705587129, 0.33561146807260173), (8, 8.797215574852185, 0.32094724030435973))

所以,到目前为止一切正常。 问题是,如果出于某种原因我想重复计算,例如测量时间,我会得到:

>>> del a,b,c,d
>>> a,b,c,d = izip(*gen)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: need more than 0 values to unpack

所以我不明白:

  1. 为什么它以前有效而现在无效
  2. 为什么说“需要超过 0 个值才能解压”??我认为我做得很好。

注意:

如果有人想建议任何其他方式来产生这 4 个值,那将是非常受欢迎的。

【问题讨论】:

  • 这是预期的行为。生成器生成一次值。
  • 谢谢,是的,其他人也有同样的回答。这是我的错误,因为我认为生成器对象将始终可用

标签: python tuples generator yield


【解决方案1】:

生成器的全部意义在于它只生成一次的值,并且不将值保存在内存中。

如果您想重用这些值,则必须通过再次调用原始函数来创建新的生成器,或者使用 list 代替生成器。

要创建一个新的生成器,只需重复两个语句:

>>gen = pro.processTable(pathToPyTable, testPages)
>>a,b,c,d = izip(*gen)

如果您想要一个列表而不修改生成器代码,您可以使用列表解析来捕获生成器的输出。

gen = [x for x in pro.processTable(pathToPyTable, testPages)]

【讨论】:

  • 也就是说,每次要迭代gen时都需要重新运行gen = pro.processTable(pathToPyTable, testPages)
  • 好的,我知道它在内存中保存了值,但是我不知道您每次都必须创建一个新的生成器。我想,既然生成器是一个对象,你创建它:gen = pro.processTable(pathToPyTable, testPages) 然后你可以随时使用它
  • @user2919052,不,它被消耗掉了。
  • 是的,我不会在 5 分钟之前接受,但别担心我会的!!
猜你喜欢
  • 1970-01-01
  • 2016-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-13
  • 2011-03-02
相关资源
最近更新 更多