Python itertools.ifilter与filter与列表理解

Python itertools.ifilter与filter与列表理解,python,function,module,built-in,Python,Function,Module,Built In,我正试图更加熟悉itertools模块,并找到了一个名为ifilter的函数 据我所知,它根据给定的函数过滤和iterable,并返回一个迭代器,该迭代器覆盖一个列表,该列表包含iterable的元素,函数的计算结果为True 问题1:到目前为止我的理解正确吗 问题2:除了返回和迭代器之外,它与内置的过滤器函数有何不同 问题3哪个更快 据我所知,情况并非如此。我错过什么了吗?(我进行了以下测试) itertools.ifilter(λx:x%2,范围(5)) >>>对于itertools.ifi

我正试图更加熟悉
itertools
模块,并找到了一个名为
ifilter
的函数

据我所知,它根据给定的函数过滤和iterable,并返回一个迭代器,该迭代器覆盖一个列表,该列表包含iterable的元素,函数的计算结果为
True

问题1:到目前为止我的理解正确吗

问题2:除了返回和迭代器之外,它与内置的
过滤器
函数有何不同

问题3哪个更快

据我所知,情况并非如此。我错过什么了吗?(我进行了以下测试)

itertools.ifilter(λx:x%2,范围(5)) >>>对于itertools.ifilter中的i(λx:x%2,范围(5)):打印i ... 1. 3. >>>过滤器(λx:x%2,范围(5)) [1, 3] >>>函数=λx:x%2 >>>[范围(5)内项目的项目,如果功能(项目)] [1,3]
ifilter
返回生成器,而不是列表


生成器在需要时动态创建项目,而不是首先分配整个列表。这是
ifilter
filter

之间的唯一区别。在这里,您可以看到区别:

从iterable的那些元素构造一个列表,函数将为其返回true

制作一个从iterable中筛选元素,只返回谓词为True的元素


这意味着要获得“ifilter”项,您应该使用返回的迭代器进行迭代,但“filter”返回列表中的所有元素,而不需要进行迭代。

您的理解是正确的:唯一的区别是
ifilter
返回迭代器,而使用
filter
类似于调用:

list(ifilter(...))
您可能还对filter和ifilter的内容感兴趣:

列表理解大大减少了对
filter()
map()
的需要。同样地,生成器表达式也希望尽量减少对
itertools.ifilter()
itertools.imap()
的需求。[……]


还请注意,
ifilter
在Python-3中变成了
filter
(因此从itertools中删除)。

下面的示例包括一个数字生成器,它在生成数字之前立即打印消息,显示了
filter()
如何首先构建列表,然后运行该列表并对其进行过滤。然而,
itertools.ifilter
会按原样过滤,从不建立列表。如果要筛选500000个重要内容,则需要
ifilter
,因此不需要构建列表

import itertools

def number_generator():
    for i in range(0, 3):
        print "yield", i
        yield i
    print "stopping"

function = lambda x: x > 0

numbers = number_generator()
print "itertools.ifilter:"
for n in itertools.ifilter(function, numbers):
    print n

print "\nfilter:"
numbers = number_generator()
for n in filter(function, numbers):
    print n
输出:

itertools.ifilter: yield 0 yield 1 1 yield 2 2 stopping filter: yield 0 yield 1 yield 2 stopping 1 2 itertools.ifilter: 收益率0 收益率1 1. 收益率2 2. 停止 过滤器: 收益率0 收益率1 收益率2 停止 1. 2.
你期望的产量是多少<代码>范围(5)将为您提供
[0,1,2,3,4]
。请注意,过滤器的大多数用法都可以用生成器/列表表达式上的保护来替代:
列表(x代表范围(5)中的x,如果x%2)
生成器是迭代器,严格来说,它返回一个itertools.ifilter对象。 itertools.ifilter: yield 0 yield 1 1 yield 2 2 stopping filter: yield 0 yield 1 yield 2 stopping 1 2