[Python-ideas] Predicate Sets

spir denis.spir at gmail.com
Mon Jan 20 22:53:09 CET 2014


On 01/20/2014 12:41 AM, Daniel da Silva wrote:
> Below is a description of a very simple but immensely useful class called a
> "predicate set". In combination with the set and list comprehensions they
> would allow another natural layer of reasoning with mathematical set logic
> in Python.
>
> In my opinion, a concept like this would be best located in the functools
> module.
>
>
> *Overview:*
>      Sets in mathematics can be defined by a list of elements without
> repetitions, and alternatively by a predicate (function) that determines
> inclusion. A predicate set would be a set-like class that is instantiated
> with a predicate function that is called to determine ``a in
> the_predicate_set''.
>
>>> myset = predicateset(lambda s: s.startswith('a'))
>>> 'xyz' in myset
> False
>>> 'abc' in myset
> True
>>> len(myself)
> Traceback (most recent call last):
>    [...]
> TypeError
>
> *Example Uses:*
> # Dynamic excludes in searching
> foo_files = search_files('foo', exclude=set(['a.out', 'Makefile']))
> bar_files = search_files('bar', exclude=predicateset(lambda fname: not
> fname.endswith('~'))) # exclude *~
>
> # Use in place of a set with an ORM
> validusernames = predicateset(lambda s: re.match(s, '[a-zA-Z0-9]+'))
>
> class Users(db.Model):
>      username = db.StringProperty(choices=validusernames)
>      password = db.StringProperty()

While the theoretical interest is clear, I don't see the actual point. A 
predicate set without any actual set (in the ordinary prog sense) is just a 
criterion function (the predicate) returning a logical true/false, right? (Note: 
any logical func, any logical expression on a variable, does define a predicate 
set, doesn't it?) So, we already have this builtin ;-).

>>> crit = lambda s: s.startswith('a')
>>> crit("xyz")
False
>>> crit("abc")
True

One could make a trivial class to build such constructs as objects and implement 
the 'in' operator for them.

class PredSet:
     def __init__ (self, crit):
         self.crit = crit
     def __contains__ (self, x):
         return self.crit(x)


crit = lambda s: s.startswith('a')
s = PredSet(crit)
print("xyz" in s, "abc" in s)

But I don't see any advantage in terms of clarity: crit(x) is as clear, isn't it.

One also could add an actual set to such objects, which would automagically put 
items inside, eg whenever they are checked via the criterion func. (Somewhat 
like string pools.)

class PredSet:
     def __init__ (self, crit):
         self.crit = crit
         self.items = set()
     def __contains__ (self, x):
         if self.crit(x):
             self.items.add(x)
             return True
         return False

s = PredSet(crit)
print("xyz" in s, "abc" in s, "ablah" in s)
print(s.items)

Would certainly be nice, but I cannot see any usage. All in all, I guess I'm 
missing the actual point.

Denis










More information about the Python-ideas mailing list