80
>>> n = [1,2,3,4]

>>> filter(lambda x:x>3,n)
<filter object at 0x0000000002FDBBA8>

>>> len(filter(lambda x:x>3,n))
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    len(filter(lambda x:x>3,n))
TypeError: object of type 'filter' has no len()

我无法得到我得到的列表的长度。所以我尝试将它保存到一个变量中,就像这样......

>>> l = filter(lambda x:x>3,n)
>>> len(l)
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    len(l)
TypeError: object of type 'filter' has no len()

而不是使用循环,有什么办法可以得到这个的长度?

4

5 回答 5

112

您必须以某种方式遍历过滤器对象。一种方法是将其转换为列表:

l = list(filter(lambda x: x > 3, n))

len(l)  # <--

但这可能会filter()首先破坏使用的意义,因为您可以使用列表推导更轻松地做到这一点:

l = [x for x in n if x > 3]

再次,len(l)将返回长度。

于 2013-10-04T13:18:34.040 回答
33

这是一个老问题,但我认为这个问题需要使用map-reduce思想来回答。所以在这里:

from functools import reduce

def ilen(iterable):
    return reduce(lambda sum, element: sum + 1, iterable, 0)

ilen(filter(lambda x: x > 3, n))

如果n不适合计算机内存,这尤其好。

于 2017-06-04T07:14:42.297 回答
17

将过滤器转换为列表会占用额外的内存,这对于大量数据可能是不可接受的。您可以在不将其转换为列表的情况下找到过滤器对象的长度:

sum(1 for _ in filter(lambda x: x > 3, n))

于 2018-07-14T06:41:08.087 回答
13

python 3的文档说它返回一个迭代器

“从函数返回 true 的那些可迭代元素构造一个迭代器。”

在 python 2 中,它返回了一个列表:请参见此处。您将需要迭代过滤器对象以找到它的长度。

于 2013-10-04T13:23:24.257 回答
12

通常,filter并且reduce不是pythonic。

@arshajii 提到了这个解决方案:

len([x for x in n if x > 3])

这很简单,但并没有描述您真正想要做什么,它会创建一个可能会使用一些额外内存的列表。更好的解决方案是使用sum生成器:

sum(1 for x in n if x > 3)

(在此处查看有关生成器的更多信息:https ://www.python.org/dev/peps/pep-0289/#rationale )

然而,sum由于实现(在 CPython 3.6.4 中测试),在大多数情况下,使用生成器实际上更慢:

In [1]: %timeit len([1 for x in range(10000000)])
356 ms ± 17.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [2]: %timeit sum(1 for x in range(10000000))
676 ms ± 7.05 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
于 2018-06-14T08:16:06.537 回答