itertools.ifilter与过滤器列表理解

时间:2012-01-24 21:19:34

标签: python function module built-in

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

根据我的理解,它基于给定的函数进行过滤和迭代,并在包含函数求值为True的iterable元素的列表上返回一个迭代器。

问题1 :到目前为止我的理解是否正确?

问题2 :除了返回和迭代器之外,它与内置filter函数有什么不同?

问题3 哪个更快?

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

>>> itertools.ifilter(lambda x: x%2, range(5))
<itertools.ifilter object at 0x7fb1a101b210>
>>> for i in itertools.ifilter(lambda x: x%2, range(5)): print i
... 
1
3
>>> filter(lambda x: x%2, range(5))
[1, 3]
>>> function = lambda x: x%2
>>> [item for item in range(5) if function(item)]
[1,3]

4 个答案:

答案 0 :(得分:19)

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

list(ifilter(...))

您可能也对PEP 289关于过滤器和ifilter的说法感兴趣:

  

列表推导大大减少了对filter()map()的需求。同样,生成器表达式可以最大限度地减少对itertools.ifilter()itertools.imap()的需求。 [...]

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

答案 1 :(得分:14)

下面的示例包括一个数字生成器,它在产生数字之前立即打印消息,显示filter()首先构建列表的方式,然后运行并过滤它。尽管itertools.ifilter过滤了,但从不构建列表。如果您要过滤500,000个重要内容,则需要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

答案 2 :(得分:3)

ifilter返回一个生成器,而不是列表。

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

之间的唯一区别

答案 3 :(得分:2)

在这里,您可以看到差异:

filter(function, iterable)从iterable的那些元素构造一个列表,函数返回true。

itertools.ifilter(predicate, iterable)制作一个iterator ,过滤来自iterable的元素,只返回谓词为True的元素。

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