在发电机上使用继续

时间:2014-08-23 12:18:12

标签: python

我尝试使用continue函数跳过不符合特定条件的生成项目。

如果我只是打印x,我会得到完整的输出:

>>> w = [1,4,6,10]
>>> w2 = ((2 * x) for x in w)
>>> for x in w2: print x
...
2
8
12
20

然而,当我尝试使用continue不打印8时,我得到一个空格作为输出。

>>> for x in w2:
...     if x == 8: continue
...     print x
...
>>>

我试图在第二次迭代中获得2,12,20的输出。我如何得到所需的输出?

2 个答案:

答案 0 :(得分:2)

生成器与列表不同,因为它在需要时生成元素,并且这些元素不会在内存中保留元素。一旦你完成了所有的元素,当你再次尝试迭代它们时,生成器将不会打印任何内容,因为它已经被使用过了。

很可能你已经在第一个for循环中使用了生成器,所以当你尝试再次迭代它时,它是空的。尝试print list(w2)而不是循环来检查你的元素是否存在。

实施例

让我们定义一个函数,将函数从iterable打印到值:

def printuntil(iterable, stopval):
    for item in iterable:
       print item
       if item == stopval:
           break

现在让我们用列表尝试两次:

>>> vals = [2 * x for x in range(3)]
>>> printuntil(vals, 2)
0
2
>>> printuntil(vals, 4)
0
2
4

一切似乎都好,让我们用发电机做同样的事情:

>>> vals = (2 * x for x in range(3))
>>> printuntil(vals, 2)
0
2
>>> printuntil(vals, 4)
4

正如您可以看到已经消耗的数字02,因此第二次调用会打印尚未使用的第一个元素:4。因此,如果要迭代多次迭代,请使用列表。

复制生成器

您可以在使用itertools.tee使用之前复制生成器,这样您就可以在列表中保存元素。

>>> vals = (2 * x for x in range(5))
>>> from itertools import tee
>>> vals, valscopy = tee(vals)
>>> printuntil(vals, 2)
0
2
>>> printuntil(valscopy, 4)
0
2
4

这将节省内存但不提高性能,因为必须始终生成元素。

答案 1 :(得分:1)

>>> w=[1,4,6,10]
>>> w2=((2 * x) for x in w)
>>> for x in w2:
...     print x
... 
2
8
12
20
>>> w2=((2 * x) for x in w)
>>> for x in w2:
...     if x == 8: continue
...     print x
... 
2
12
20

给出正确的结果?!

你必须在每次循环之前使用w2=((2 * x) for x in w)(如果你在终端上,正如enrico.bacis所解释的那样。);更好地使用IDE。 IDLE也可以。如果您仍希望成为命令行,请更好地制作function