List querying capabilities in Python 3.x
The _operators attribute is not specific to an instance but a common mapping table that can be shared by all instances, so it could be turned into a class attribute instead.

The case of an unsupported operator is not handled. The class happily keys the user create a condition with an unsupported operator, and the program will crash later. Always validate the received function parameters, and signal problems as early as possible.

After the condition is created, there's no need to hold on to the string representation of the operator only to lookup the real operator in the common mapping table. Better to lookup once, in the constructor, and store the real operator, not its string representation.

If a condition has two modes, non-reverse and reverse, consider using a boolean to represent that. Forcing the user to remember to pass on the right magic string is not very user friendly and prone to errors. If you use a boolean, there are 2 possible values, instead of an infinite spacer of invalid values. More intuitive api, and higher chance that users get it right.

These conditions cannot both be true at the same time:

            if compare_type.lower() == "non-reverse":
                # ...
            if compare_type.lower() == "reverse":


So the second one should be an elif. Converting the compare type variable to lower case twice is also not pretty.

I think par of the reason the current implementation feels clunky is that it is not fluent. For example, a fluent api to select a list of name-email pairs from a collection objects, matching a name, ordered by age, look something like this:

queryset.where(name="Jack").order_by("age").select("name", "email")


disclaimer: inspired by queries in Django