【问题标题】:itertools.ifilter Vs. filter Vs. list comprehensionsitertools.ifilter 对比过滤器对比列表推导
【发布时间】:2018-08-09 08:54:56
【问题描述】:

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

据我了解,它根据给定函数过滤和迭代,并在包含迭代元素的列表上返回一个迭代器,该函数在其上计算为True

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

问题2:除了this返回和迭代器之外,它与内置的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]

【问题讨论】:

  • 您期望的输出是什么? range(5) 会给你[0,1,2,3,4]
  • 请注意,过滤器的大多数用法都可以替换为生成器/列表表达式上的守卫:list(x for x in range(5) if x%2)

标签: python function module built-in


【解决方案1】:

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

list(ifilter(...))

您可能还对PEP 289 所说的 filter 和 ifilter 感兴趣:

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

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

【讨论】:

    【解决方案2】:

    下面的示例包含一个数字生成器,它在生成数字之前立即打印一条消息,显示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: 产量 0 产量 1 1 产量 2 2 停止 筛选: 产量 0 产量 1 产量 2 停止 1 2

    【讨论】:

      【解决方案3】:

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

      生成器在需要时动态创建它们的项目,而不是首先分配整个列表。这是ifilterfilter 之间的唯一区别

      【讨论】:

      • 生成器是一个迭代器,严格来说它返回一个 itertools.ifilter 对象。
      【解决方案4】:

      在这里,您可以看到不同之处:

      filter(function, iterable)构造一个列表,由函数返回 true 的可迭代元素组成。

      itertools.ifilter(predicate, iterable)创建一个iterator,从可迭代中过滤元素,只返回谓词为 True 的元素。

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

      【讨论】:

        猜你喜欢
        • 2012-06-22
        • 2014-02-10
        • 1970-01-01
        • 2013-08-19
        • 2017-03-24
        • 2017-09-27
        • 2017-11-19
        • 1970-01-01
        • 2019-05-25
        相关资源
        最近更新 更多