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)

Answer from TobiMarg on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org › python › filter-in-python
filter() in python - GeeksforGeeks
Return Value: A filter object (an iterator), which can be converted into a list, tuple, set, etc. Let's explore some examples of filter() function and see how it is used. This code defines a regular function to check if a number is even and then uses filter() to extract all even numbers from a list. Python ·
Published   September 1, 2025
Top answer
1 of 5
127

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)

2 of 5
10

filter expects to get a function and something that it can iterate over. The function should return True or False for each element in the iterable. In your particular example, what you're looking to do is something like the following:

In [47]: def greetings(x):
   ....:     return x == "hello"
   ....:

In [48]: filter(greetings, ["hello", "goodbye"])
Out[48]: ['hello']

Note that in Python 3, it may be necessary to use list(filter(greetings, ["hello", "goodbye"])) to get this same result.

🌐
DigitalOcean
digitalocean.com › community › tutorials › how-to-use-the-python-filter-function
How To Use the Python Filter Function | DigitalOcean
July 24, 2020 - The Python built-in filter() function can be used to create a new iterator from an existing iterable (like a list or dictionary) that will efficiently filter out elements using a function that we provide. An iterable is a Python object that can be “iterated over”, that is, it will return ...
🌐
Real Python
realpython.com › python-filter-function
Python's filter(): Extract Values From Iterables – Real Python
July 31, 2023 - Python iterators are well known to be memory efficient. In your example about positive numbers, you can use filter() along with a convenient predicate function to extract the desired numbers. To code the predicate, you can use either a lambda or a user-defined function: ... >>> numbers = [-2, -1, 0, 1, 2] >>> # Using a lambda function >>> positive_numbers = filter(lambda n: n > 0, numbers) >>> positive_numbers <filter object at 0x7f3632683610> >>> list(positive_numbers) [1, 2] >>> # Using a user-defined function >>> def is_positive(n): ...
🌐
FavTutor
favtutor.com › blogs › filter-list-python
Python filter() Function: 5 Best Methods to Filter a List
November 11, 2023 - The filter method is more efficient than the for-loop because it returns a filter object, which is an iterator that yields values on demand, promoting a lazy evaluation strategy.
🌐
Mimo
mimo.org › glossary › python › filter
Python filter(): Syntax, Usage, and Examples
It's particularly useful when working with various data structures in Python. The built-in filter() function creates an iterator from an iterable (like a list) by keeping only the items for which a given function returns True. It provides a clean, functional way to select a subset of data.
Top answer
1 of 4
4

The OP wants to do this MyData.objects.filter(id>1).

Let's face it.

The problem is Python is greedy (eagerly evaluates expressions), not lazy like Haskell.
Watch David Beazley - Lambda Calculus from the Ground Up - PyCon 2019 for mind-bending λ thing.

Python evaluates id > 1 before calling filter. If we can stop the evaluation for now, we can pass the expression unevaluated to the filter function.

But we can delay expression evaluation until required if we enclose the expression in a function. That's the idea.

The function interface would be filter(lambda: id > 1) if we could implement it. This interface will be super versatile because any Python expression can be passed and abused.

The implementation;

if we invoke the lambda or any other function with the expression id > 1, Python looks up the name id in the local, enclosing, global scope or builtins depending on the context where the function is invoked.

If we can introduce an object with the name id somewhere in the look-up path before Python finds id in the builtins we can redefine the semantics of the expression.

I'm gonna do it with eval which evaluates expressions in the given context.

CopyDATA = [
    {'id': 1, 'name': 'brad', 'color':'red'},
    {'id': 2, 'name': 'sylvia', 'color':'blue'},
]

def myfilter(a_lambda):
    return filter(lambda obj: eval(a_lambda.__code__, obj.copy()),
    DATA)

I pass a dict.copy to eval because eval modifies it's globals object.

See it in action in the context of Model class

CopyIn [1]: class Data(Model):
   ...:     name = str()
   ...:     id = int()
   ...:     color = str()
   ...: 

In [2]: Data.objects.create(**{"id": 1, "name": "brad", "color": "red"})

In [3]:     Data.objects.create(**{"id": 2, "name": "sylvia", "color": "blue"})

In [4]:     Data.objects.create(**{"id": 3, "name": "paul", "color": "red"})

In [5]:     Data.objects.create(**{"id": 4, "name": "brandon", "color": "yello"})

In [6]:     Data.objects.create(**{"id": 5, "name": "martin", "color": "green"})

In [7]:     Data.objects.create(**{"id": 6, "name": "annie", "color": "gray"})

In [8]: pprint([vars(obj) for obj in Data.objects.filter(lambda: id == 1)])
[{'color': 'red', 'id': 1, 'name': 'brad'}]

In [9]: pprint([vars(obj) for obj in Data.objects.filter(lambda: 1 <= id <= 2)])
[{'color': 'red', 'id': 1, 'name': 'brad'},
 {'color': 'blue', 'id': 2, 'name': 'sylvia'}]

In [10]: pprint([vars(obj) for obj in Data.objects.filter(lambda: color == "blue")])
[{'color': 'blue', 'id': 2, 'name': 'sylvia'}]

In [11]: pprint([vars(obj) for obj in Data.objects.filter(lambda: "e" in color and (name is "brad" or name is "sylvia"))])
[{'color': 'red', 'id': 1, 'name': 'brad'},
 {'color': 'blue', 'id': 2, 'name': 'sylvia'}]

In [12]: pprint([vars(obj) for obj in Data.objects.filter(lambda: id % 2 == 1)])
[{'color': 'red', 'id': 1, 'name': 'brad'},
 {'color': 'red', 'id': 3, 'name': 'paul'},
 {'color': 'green', 'id': 5, 'name': 'martin'}]

The Data class inherits from Model. The Model gives Data the __init__ method and a class attribute named objects that points to a MetaManager instance which is a descriptor.

The MetaManager returns a Manager instance to sub classes of Model upon access of objects attribute from the subclass. The MetaManger identifies the accessing class and passes that to the Manager instance. The Manager handles object creation, persistence and fetch.

The db is implemented as a class attribute of Manager for simplicity.

To stop abuse with global objects via functions the filter function raises an exception if a lambda is not passed.

Copyfrom collections import defaultdict
from collections.abc import Callable


class MetaManager:
    def __get__(self, obj, objtype):
        if obj is None:
            return Manager(objtype)
        else:
            raise AttributeError(
                "Manger isn't accessible via {} instances".format(objtype)
            )


class Manager:
    _store = defaultdict(list)

    def __init__(self, client):
        self._client = client
        self._client_name = "{}.{}".format(client.__module__, client.__qualname__)

    def create(self, **kwargs):
        self._store[self._client_name].append(self._client(**kwargs))

    def all(self):
        return (obj for obj in self._store[self._client_name])

    def filter(self, a_lambda):
        if a_lambda.__code__.co_name != "<lambda>":
            raise ValueError("a lambda required")

        return (
            obj
            for obj in self._store[self._client_name]

            if eval(a_lambda.__code__, vars(obj).copy())
        )


class Model:
    objects = MetaManager()

    def __init__(self, **kwargs):
        if type(self) is Model:
            raise NotImplementedError

        class_attrs = self.__get_class_attributes(type(self))

        self.__init_instance(class_attrs, kwargs)

    def __get_class_attributes(self, cls):
        attrs = vars(cls)
        if "objects" in attrs:
            raise AttributeError(
                'class {} has an attribute named "objects" of type "{}"'.format(
                    type(self), type(attrs["objects"])
                )
            )
        attrs = {
            attr: obj
            for attr, obj in vars(cls).items()
            if not attr.startswith("_") and not isinstance(obj, Callable)
        }
        return attrs

    def __init_instance(self, attrs, kwargs_dict):
        for key, item in kwargs_dict.items():
            if key not in attrs:
                raise TypeError('Got an unexpected key word argument "{}"'.format(key))
            if isinstance(item, type(attrs[key])):
                setattr(self, key, item)
            else:
                raise TypeError(
                    "Expected type {}, got {}".format(type(attrs[key]), type(item))
                )


if __name__ == "__main__":
    from pprint import pprint

    class Data(Model):
        name = str()
        id = int()
        color = str()

    Data.objects.create(**{"id": 1, "name": "brad", "color": "red"})
    Data.objects.create(**{"id": 2, "name": "sylvia", "color": "blue"})
    Data.objects.create(**{"id": 3, "name": "paul", "color": "red"})
    Data.objects.create(**{"id": 4, "name": "brandon", "color": "yello"})
    Data.objects.create(**{"id": 5, "name": "martin", "color": "green"})
    Data.objects.create(**{"id": 6, "name": "annie", "color": "gray"})

    pprint([vars(obj) for obj in Data.objects.filter(lambda: id == 1)])
    pprint([vars(obj) for obj in Data.objects.filter(lambda: 1 <= id <= 2)])
    pprint([vars(obj) for obj in Data.objects.filter(lambda: color == "blue")])
    pprint(
        [
            vars(obj)
            for obj in Data.objects.filter(
                lambda: "e" in color and (name is "brad" or name is "sylvia")
            )
        ]
    )
    pprint([vars(obj) for obj in Data.objects.filter(lambda: id % 2 == 1)])
2 of 4
2

If you want the full django Model experience, i.e.:

  • create a new feature vector or data entry with datapoint = MyData(name='johndoe', color='green', ...) just like in django: e.g. new_user=User(username='johndoe', email='jd@jd.com');
  • use the MyData.objects for object management, like MyData.objects.filter(color__eq='yellow');

here is an approach on how the logic could look like.

First you need basically a naive ObjectManager class:

Copyimport collections
import operator
import inspect

class ObjectManager(collections.MutableSet):
    def __init__(self):
        # this will hold a list of all attributes from your custom class, once 
        # initiated
        self._object_attributes = None
        self._theset = set()
    def add(self, item):
        self._theset.add(item)
    def discard(self, item):
        self._theset.discard(item)
    def __iter__(self):
        return iter(self._theset)
    def __len__(self):
        return len(self._theset)
    def __contains__(self, item):
        try:
            return item in self._theset
        except AttributeError:
            return False

    def set_attributes(self, an_object):
        self._object_attributes = [
            a[0] for a in  inspect.getmembers(
                an_object, lambda a:not(inspect.isroutine(a))
            ) if not(a[0].startswith('__') and a[0].endswith('__'))
            ]

    def filter(self, **kwargs):
        """Filters your objects according to one or several conditions

        If several filtering conditions are present you can set the 
        combination mode to either 'and' or 'or'.
        """
        mode = kwargs.pop('mode', 'or')
        ok_objects = set()
        for kw in kwargs:
            if '__' in kw:
                _kw, op = kw.split('__')
                # only allow valid operators
                assert op in ('lt', 'le', 'eq', 'ne', 'ge', 'gt')
            else:
                op = 'eq'
                _kw = kw
            _oper = getattr(operator, op)
            # only allow access to valid object attributes
            assert _kw in self._object_attributes
            n_objects = (
                obj for obj in self 
                if _oper(getattr(obj, _kw), kwargs[kw])
                )
            if mode == 'and':
                if n_objects:
                    ok_objects = ok_objects.intersection(n_objects)\
                        if ok_objects else set(n_objects)
                else:
                    return set()

            else:
                ok_objects.update(n_objects)
        return ok_objects

    # feel free to add a `get_or_create`, `create`, etc. 

Now you attach an instance of this class as attribute to your MyData class and make sure all new objects are added to it:

Copyclass MyData:
    # initiate the object manager
    objects = ObjectManager()

    def __init__(self, uid, name, color):
        self.uid = uid
        self.name = name
        self.color = color

        # populate the list of query-able attributes on creation
        # of the first instance
        if not len(self.objects):
            self.objects.set_attributes(self)
        # add any new instance to the object manager
        self.objects.add(self)

Now you can import your feature vector:

CopyDATA = [
    {'uid': 1, 'name': 'brad', 'color':'red'},
    {'uid': 2, 'name': 'sylvia', 'color':'blue'},
]
for dat in DATA:
    myData(**dat)

or create new instances:

Copyd1 = MyData(uid=10, name='john', color='yellow')

and make use of the manager to filter your objects:

Copyprint([md.name for md in MyData.objects.filter(uid__ge=10)])
# > ['john']
print([md.name for md in MyData.objects.filter(mode='and',uid__ge=1,name__eq='john')])
# > ['john']
print([md.name for md in MyData.objects.filter(mode='or',uid__le=4,name__eq='john')])
# > ['john', 'brad', 'sylvia']


If you cannot or don't want to change the class you want an object manager for, and you are willing to monkey patch around (note that I'm not advertising this!) you can even create a ObjectManager that can be hooked to an arbitrary class (built-in types won't work though) after definition or even initiation of some instances.

The idea is to monkey patch __init__ of the target class and add the objects attribute upon init of an instance of your ObjectManager:

Copyimport gc
import inspect
import collections
import operator
import wrapt  # not standard lib > pip install wrapt

class ObjectManager(collections.MutableSet):
    def __init__(self, attach_to):
        self._object_attributes = None
        # add self as class attribute
        attach_to.objects = self
        # monkey patch __init__ of your target class
        @wrapt.patch_function_wrapper(attach_to, '__init__')
        def n_init(wrapped, instance, args, kwargs):
            wrapped(*args, **kwargs)
            c_objects = instance.__class__.objects
            if not c_objects:
                c_objects.set_attributes(instance)
            c_objects.add(instance)
        # make sure to be up to date with the existing instances
        self._theset = set(obj for obj in gc.get_objects() if isinstance(obj, attach_to))
        # already fetch the attributes if instances exist
        if self._theset:
            self.set_attributes(next(iter(self._theset)))
        ...
        # the rest is identical to the version above

So now this is how you would use it:

Copyclass MyData:

    def __init__(self, uid, name, color):
        self.uid = uid
        self.name = name
        self.color = color

# create some instances
DATA = [
    {'uid': 1, 'name': 'brad', 'color':'red'},
    {'uid': 2, 'name': 'sylvia', 'color':'blue'},
]
my_datas = []
for dat in DATA:
    my_datas.append(myData(**dat))  # appending them just to have a reference
# say that ONLY NOW you decide you want to use an object manager
# Simply do:
ObjectManager(MyData)
# and you are done:
print([md.name for md in MyData.objects.filter(mode='or',uid__le=4,name__eq='john')])
# > ['brad', 'sylvia']
# also any object you create from now on is included:
d1 = MyData(uid=10, name='john', color='yellow')
print([md.name for md in MyData.objects.filter(mode='or',uid__le=4,name__eq='john')])
# > ['brad', 'sylvia', 'john']
🌐
W3Schools
w3schools.com › python › ref_func_filter.asp
Python filter() Function
Python Examples Python Compiler Python Exercises Python Quiz Python Challenges Python Server Python Syllabus Python Study Plan Python Interview Q&A Python Bootcamp Python Certificate Python Training ... ages = [5, 12, 17, 18, 24, 32] def myFunc(x): if x < 18: return False else: return True adults = filter(myFunc, ages) for x in adults: print(x) Try it Yourself »
Find elsewhere
🌐
DataCamp
datacamp.com › tutorial › python-filter
Python filter(): Keep What You Need | DataCamp
June 27, 2025 - If the test passes (read: if your function returns True) filter() keeps it. Otherwise, it skips the item. This is pretty self-explanatory, so let's continue. ... function: Specifies the test you want to apply to each item. It should take one argument and return True or False. iterable: Provides a list, tuple, string, or any object you can loop over.
🌐
ThePythonGuru
thepythonguru.com › python-builtin-functions › filter
Python filter() function - ThePythonGuru.com
Syntax: filter(function or None, iterable) --> filter object · Here is an example: Python 3 · Try it out: def is_even(x): if x % 2 == 0: return True else: return False f = filter(is_even, [1, 3, 10, 45, 6, 50]) print(f) for i in f: print(i) Output · Input · To produce the result at once we can use the list() function.
🌐
Real Python
realpython.com › ref › builtin-functions › filter
filter() | Python’s Built-in Functions – Real Python
The built-in filter() function in Python is used to process an iterable and extract items that satisfy a given condition, as determined by a filtering function. filter() returns an iterator that yields only the elements for which the filtering ...
🌐
AskPython
askpython.com › home › python filter() function
Python filter() function - AskPython
August 6, 2022 - Python's filter() function is used to filter the elements of an iterable (sequence) with the help of a predicate that tests each element on the iterable.
🌐
Python Morsels
pythonmorsels.com › map-and-filter-python
Python's map and filter functions - Python Morsels
July 26, 2021 - Let's talk about the map and filter functions in Python, the differences between them, and why I don't usually recommend using them (related: I also don't recommend lambda expressions). The map function accepts a function and an iterable. Here we're passing a square function and a numbers list to map: >>> def square(n): ... return n**2 ... >>> numbers = [2, 1, 3, 4, 7, 11, 18] >>> squared_numbers = map(square, numbers) ... As we loop over this map object ...
🌐
Paigeniedringhaus
paigeniedringhaus.com › blog › filter-merge-and-update-python-lists-based-on-object-attributes
Filter, Merge, and Update Python Lists Based on Object Attributes | Paige Niedringhaus
if __name__ == '__main__': scraper = ForSaleNFTScraper(); cards = scraper.get_cards(max_card_count=200) card_data = [] for card in cards: info = (scraper.get_nft_data(card)) card_data.append(info) # filter out any extra cards that aren't for sale cards_for_sale = scraper.filter_priced_cards(card_data) # filter out any extra cards that aren't for sale cards_for_sale = scraper.filter_priced_cards(card_data) All right, here’s the last Python list manipulation tip I’ll be sharing in this post: how to add new properties to each object in a list.
🌐
Python Reference
python-reference.readthedocs.io › en › latest › docs › functions › filter.html
filter — Python Reference (The Right Way) 0.1 documentation
Note that filter(function, iterable) is equivalent to [item for item in iterable if function(item)] if function is not None and [item for item in iterable if item] if function is None.
🌐
Reddit
reddit.com › r/learnpython › python filter a list of class objects by class method using filter built-in function problem
r/learnpython on Reddit: Python filter a list of class objects by class method using Filter built-in function problem
January 21, 2022 -

Like ok... the title said it all. For example : I have a list filled by class name Food. The class uniqueness are defined by name and price attribute. And I create a method to check if the Food is free. the question is how do I use the method to filter the list of Food class using the free checking method of food class?

@dataclass
class Food:
    name : str
    price : int

    def isfree(self):
        return self.price == 0

food_list = [Food(name = "curry", price = 5), Food(name = "sushi", price = 0)]
filtered_list = filter(Food.isfree, food_list) # got error TypeError: isfree() takes 0 positional arguments but 2 were given
🌐
TechBeamers
techbeamers.com › python-filter-function
Python Filter Function - TechBeamers
April 18, 2025 - # Python filter() syntax filter(in_function|None, iterable) |__filter object
🌐
Note.nkmk.me
note.nkmk.me › home › python
Filter (Extract/Remove) Items of a List with in Python: filter() | note.nkmk.me
May 15, 2023 - In Python, you can use filter() to filter (extract/remove) items of a list, tuple, or other iterable that satisfy the conditions. Built-in Functions - filter() — Python 3.11.3 documentation Basic usa ...
🌐
Codecademy
codecademy.com › docs › python › built-in functions › filter()
Python | Built-in Functions | filter() | Codecademy
March 26, 2022 - The filter() function returns a filter object that contains values from an iterable. If a function returns True for a given item’s value, that value will be included in the returned object.
🌐
Palantir Developer Community
community.palantir.com › ask the community
Filtering object sets in a Python function - Ask the Community - Palantir Developer Community
October 20, 2024 - I have an object in my ontology (obj_foo) that i want to filter. I have an array all_ui and want to check if the object property foo_array contains any value in the array all_ui. then, i want to apply all_filters to obj_foo but the filter() method does not exist on the object. here is my current approach: filter_condition = [obj_foo.foo_array.contains(ui) for ui in all_ui] all_filters = filter_condition[0] for condition in filter_condition[1:]: all_filters |= condition filtered...