Python 在生成器上使用continue

Python 在生成器上使用continue,python,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: conti

我试图使用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的输出。如何获得所需的输出?

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

很可能您已经在第一个for循环中使用了生成器,因此当您再次尝试对其进行迭代时,它是空的。尝试
打印列表(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
正如您可以看到的,数字
0
2
已经被使用,因此第二次调用将打印第一次未被使用的元素:
4
。因此,如果您想对一个iterable进行多次迭代,请使用列表

复制发电机 您可以在使用生成器之前复制它,这样您就可以不将元素保存在列表中

>>> 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
这将是内存效率,但不是性能效率,因为必须始终生成元素

>>> 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
给出正确的结果


在for循环之前,每次都必须使用
w2=((2*x)表示w中的x)
(如果您在终端上,正如enrico.bacis所解释的);最好使用IDE。空闲也可以。如果你仍然想成为命令行的一员,请编写一个
函数

@Ben,非常感谢你编辑我的问题。你的代码输出
2,12,20
,没有空格,因此你的问题无法复制。“第一”和“第二”循环是我编辑问题的产物,试图解释OP的意思(不清楚您要求投票的内容)但这几乎肯定也是实际发生的事情。这意味着,在这种情况下,发电机不起作用,我应该使用列表。我实际上想利用发电机附带的速度优势。@enrico.bacis,您完全正确,
打印列表(w2)
给了我一个空列表。