def filter(self, **kwargs): """ 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.) """ preds = [] for k, v in iteritems(kwargs): def pred(field, value, item): # TODO: Move pred function outside of loop for suffix, p in iteritems(_BUILTIN_PREDS): 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 = ifilter(lambda item: all([f(item) for f in preds]), self) return self.__class__(gen)
def __filter_category(self, cat): return self.__class__(ifilter(lambda p: p.has_cat(cat), self))