'filters the sequence based on a set of criteria. Parameter
names should be equivalent to the properties accessible in the items
of the sequence. For example, where the items are instances of
the Stats class::
players.filter(home=True, passing_tds=1, rushing_yds=lambda x: x>0)
Returns a sequence with only players on the home team that
have a single passing touchdown and more than zero rushing yards.
If a field specified does not exist for a particular item, that
item is excluded from the result set.
If a field is set to a value, then only items with fields that equal
that value are returned.
If a field is set to a function---which must be a predicate---then
only items with field values satisfying that function will
be returned.
Also, special suffixes that begin with \'__\' may be added to the
end of a field name to invoke built in predicates.
For example, this::
players.filter(receiving_rec=lambda v: v > 0)
Is equivalent to::
players.filter(receiving_rec__gt=0)
Other suffixes includes gt, le, lt, ne, ge, etc.
(Django users should feel right at home.)'

def filter(self, **kwargs):

    preds = []
    for (k, v) in kwargs.iteritems():
        def pred(field, value, item):
            for (suffix, p) in _BUILTIN_PREDS.iteritems():
                if field.endswith(suffix):
                    f = field[:field.index(suffix)]
                    if ((not hasattr(item, f)) or (getattr(item, f) is None)):
                        return False
                    return p(getattr(item, f), value)
            if ((not hasattr(item, field)) or (getattr(item, field) is None)):
                return False
            if isinstance(value, type((lambda x: x))):
                return value(getattr(item, field))
            return (getattr(item, field) == value)
        preds.append(functools.partial(pred, k, v))
    gen = itertools.ifilter((lambda item: all([f(item) for f in preds])), self)
    return self.__class__(gen)
