How to find the length of a “filter” object in python

前端 未结 5 1502
面向向阳花
面向向阳花 2020-12-08 09:18
>>> n = [1,2,3,4]

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


>>> len(filter(lambda x:x>3,n))
Traceback         


        
相关标签:
5条回答
  • 2020-12-08 09:55

    Generally, filter and reduce are not pythonic.

    @arshajii metioned this solution:

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

    This is quite simple, but is not describing what you exactly want to do, and it makes a list that may use some additional memory. A better solution is using sum with generator:

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

    (See more about generator here: https://www.python.org/dev/peps/pep-0289/#rationale)

    However, sum with generator is actually slower in most cases because of the implementation (tested in 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)
    
    0 讨论(0)
  • 2020-12-08 09:56

    The docs for python 3 say it returns an iterator

    "Construct an iterator from those elements of iterable for which function returns true."

    In python 2 it returned a list: see here. You will need to iterate the filter object to find its length.

    0 讨论(0)
  • 2020-12-08 09:59

    This is an old question, but I think this question needs an answer using the map-reduce ideology. So here:

    from functools import reduce
    
    def ilen(iterable):
        return reduce(lambda sum, element: sum + 1, iterable, 0)
    
    ilen(filter(lambda x: x > 3, n))
    

    This is especially good if n doesn't fit in the computer memory.

    0 讨论(0)
  • 2020-12-08 10:01

    You have to iterate through the filter object somehow. One way is to convert it to a list:

    l = list(filter(lambda x: x > 3, n))
    
    len(l)  # <--
    

    But that might defeat the point of using filter() in the first place, since you could do this more easily with a list comprehension:

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

    Again, len(l) will return the length.

    0 讨论(0)
  • 2020-12-08 10:14

    Converting a filter to a list will take extra memory, which may not be acceptable for large amounts of data. You can find length of the filter object without converting it to a list:

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

    0 讨论(0)
提交回复
热议问题