A question about searching with multiple strings

Steven D'Aprano steve at REMOVETHIScyber.com.au
Sat Oct 22 06:48:29 EDT 2005


On Fri, 21 Oct 2005 13:39:17 -0700, googleboy wrote:

> Hi there.
> 
> I have defined a class called Item with several (about 30 I think)
> different attributes (is that the right word in this context?).

Generally speaking, attributes shouldn't be used for storing arbitrary
items in an object. That's what mapping objects like dicts are for. I
would change your class so that it no longer mucked about with it's
internal __dict__:

class Item():
    def __init__(self, height, length, function, **kwargs):
        # assumes that ALL items will have height, length, function
        # plus an arbitrary number (may be zero) of keyword args
        self.height = height
        self.length = length
        self.function = function
        self.data = kwargs  # store custom data in an instance attribute,
                            # NOT in the object __dict__


You would use it something like this:

def create_items():
    all_items = []
    # WARNING WARNING WARNING
    # pseudo-code -- this doesn't work because I don't
    # know what your input file looks like
    open input file
    for record in input file:
        h = read height
        l = read length
        f = read function
        D = {}
        for any more items in record:
            D[item key] = item value
        newitem = Item(h, l, f, D)
        all_items.append(newitem)
    close input file
    return all_items

Now you have processed your input file and have a list of Items. So let's
search for some!

Firstly, create a function that searches a single Item:

def SearchOneOr(source, height=None, length=None, \
                function=None, **kwargs):
    """Performs a short-circuit OR search for one or more search term."""
    if height is not None:
        if source.height == height: return True
    if length is not None:
        if source.length == length: return True
    if function is not None:
        if source.function == function: return True
    for key, value in kwargs:
        if source.data.has_key(key) and source.data[key] == value:
            return True
    return False

def SearchOneAnd(source, height=None, length=None, \
                function=None, **kwargs):
    """Performs a short-circuit AND search for one or more search term."""
    if height is not None:
        if source.height != height: return False
    if length is not None:
        if source.length != length: return False
    if function is not None:
        if source.function != function: return False
    for key, value in kwargs:
        if source.data.has_key(key) and source.data[key] != value:
            return False
        else:
            return False
    return True


Now create a function that searches all items:

def SearchAll(source_list, flag, height=None, length=None, \
              function=None, **kwargs):
    found = []
    if flag:
        search = SearchOneOr
    else:
        search = SearchOneAnd
    for source in source_list:
        if search(source, height, length, function, kwargs):
            found.append(source)
    return found

Now pass all_items to SearchAll as the first argument, and it will search
through them all and return a list of all the items which match your
search terms.

Hope this helps.


-- 
Steven.




More information about the Python-list mailing list