列出两次过滤器对象将返回一个空白列表?

use*_*937 5 python iterator python-3.x

我在Python(3.3)中使用过滤器功能.我试图将过滤器对象转换为列表.这就是我发现的:

>>> a=['1', '2', '3', None]
>>> b=filter(None,a)
>>> list(b)
['1', '2', '3']
>>> list(b)
[]
Run Code Online (Sandbox Code Playgroud)

这对我来说很奇怪.有谁能解释一下?

Mar*_*ers 8

在Python 3中,filter()返回迭代器类型,并且像所有迭代器一样,只能迭代一次.该filter()迭代器过滤的需求值,它不会在内存自身持有的任何筛选值.

您可以对列表迭代器执行相同的操作,返回者iter():

>>> a = [1, 2, 3]
>>> b = iter(a)
>>> list(b)
[1, 2, 3]
>>> list(b)
[]
Run Code Online (Sandbox Code Playgroud)

这是因为该.__next__()方法迭代,预计募集StopIteration一旦累死了,然后必须始终提高StopIteration从那里出来:

一旦迭代器的__next__()方法引发StopIteration,它必须继续在后续调用中这样做.不遵守此属性的实现被视为已损坏.

filter() 这样做是否正确:

>>> a = [1, 2, 3, None]
>>> b = filter(None, a)
>>> list(b)
[1, 2, 3]
>>> next(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
Run Code Online (Sandbox Code Playgroud)

这里next()函数调用.__next__()迭代器方法,并传播引发的异常; list()另一方面,迭代直到StopIteration,捕获该异常并返回它设法接收的任何元素的列表.

为了完整起见,在Python 2中,filter()(以及许多其他内置函数和方法)返回一个list,经常浪费内存并循环构建一个中间列表对象,然后在迭代后再次丢弃.通过返回迭代器,实现列表的选择取决于程序员.