Search code examples
pythonvariablesfiltervariable-assignment

Why does foo = filter(...) return a <filter object>, not a list?


Working in Python IDLE 3.5.0 shell. From my understanding of the builtin "filter" function it returns either a list, tuple, or string, depending on what you pass into it. So, why does the first assignment below work, but not the second (the '>>>'s are just the interactive Python prompts)

>>> def greetings():
    return "hello"

>>> hesaid = greetings()
>>> print(hesaid)
hello
>>> 
>>> shesaid = filter(greetings(), ["hello", "goodbye"])
>>> print(shesaid)
<filter object at 0x02B8E410>

Solution

  • Have a look at the python documentation for filter(function, iterable) (from here):

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

    So in order to get a list back you have to use list class:

    shesaid = list(filter(greetings(), ["hello", "goodbye"]))
    

    But this probably isn't what you wanted, because it tries to call the result of greetings(), which is "hello", on the values of your input list, and this won't work. Here also the iterator type comes into play, because the results aren't generated until you use them (for example by calling list() on it). So at first you won't get an error, but when you try to do something with shesaid it will stop working:

    >>> print(list(shesaid))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'str' object is not callable
    

    If you want to check which elements in your list are equal to "hello" you have to use something like this:

    shesaid = list(filter(lambda x: x == "hello", ["hello", "goodbye"]))
    

    (I put your function into a lambda, see Randy C's answer for a "normal" function)