[Python-ideas] Predicate Sets

Steven D'Aprano steve at pearwood.info
Tue Jan 21 03:30:29 CET 2014


On Mon, Jan 20, 2014 at 05:51:36PM -0800, Haoyi Li wrote:
> > What if you want to filter according to multiple conditions?
> 
> What's wrong with
> 
> lambda fname: func1(fname) and func2(fname) and func3(fname)

That is a single compound condition, not multiple conditions.

Think about a GUI application with a file selection dialog box, or a 
search utility. You might offer a rich set of filters, all optional, all 
selectable by the user at runtime:


[x] Hidden dot files .foo
[ ] Backup files foo~
[x] File extensions:
    [ ] Images
    [x] Text files
    [ ] Java code
    [x] Custom: [ zip,tar,foo,bar,baz ]
[x] File owner: [ steve               ]
[ ] Group:      [                     ]
[ ] Modified date between: [       ] and [       ]


etc. It's not practical to create one single giant filter function that 
looks like this:

def filter(name):
    head, ext = os.path.splitext(name)
    return ( 
            (show_hidden_dot_files and name.startswith('.')) 
            and (show_backup_tilde_files and name.endswith('~')) 
            and (show_images and ext in list_of_image_extensions)
            and ... 
            )


It would be a pain to maintain and extend, and testing would be 
horrible. Better to have each setting provide a single filter function, 
then combine the active filters into a list:

def filter(name, list_of_filters):
    for f in list_of_filters:
        if not f(name):
            return False
    return True

One might even use a class to represent the list of filters, and give it 
"all" and "any" methods, and allow multiple lists to combine so you can 
say things like:

  "show the file if *all* of these conditions are true, or if *any* of 
  these different conditions are true, but not if *any* of these 
  conditions are true"

which of course is terribly overkill for a simple file selection dialog 
box, but might be useful for a more complex search engine.

None of this should be read as supporting the original request to add 
PredicateSet into the standard library. But I encourage the OP to write 
his own library and put it on PyPI.


-- 
Steven


More information about the Python-ideas mailing list