Mimicking Django filter function
Here's some improvements you can make and some (untested) code with those improvements:


Instead of checking if the argument key contains '__' then splitting it, just split it. If it didn't contain '__' the second part will be an empty string.
Instead of through all the items and each keyword argument each time, loop through the arguments and use list comprehensions to find the matches. This way the matches list is shrinking and you don't need to look at values that matched the previous arguments. 
Instead of checking if the type of a value is string, use isinstance(obj, basestring). This will allow unicode strings also.
Instead of catching all exceptions, catch only the exceptions you expect. (others are actually errors and should be propagated to the caller).


...

def find(self, **kwargs):
    matches = self.data

    for key, key_value in kwargs.iteritems():
        # Determine if this query has extra arguments
        key_parts = key.split('__')
        attrib = key_parts[0]

        if (len(parts) &gt; 1):
            arg = key_parts[1]
            if arg not in self.query_types:
                continue

            if arg == 'contains':
                matches = [ item for item in matches if isinstance(getattr(item,arg, None), basestring) and 
                            ( key_value.lower() in getattr(item,arg, "").lower() ) ]
            elif arg == 'startswith':
                matches = [ item for item in matches if isinstance(getattr(item, arg, None), basestring) and 
                            ( getattr(item,arg, "").lower().startswith(key_value.lower()) ) ]
            elif arg == 'endswith':
                matches = [ item for item in matches if isinstance(getattr(item, arg, None), basestring) and 
                            ( getattr(item,arg, "").lower().endswith(key_value.lower()) ) ]
            elif arg == 'gt':
                matches = [ item for item in matches if self._is_int((getattr(item, arg, None)) and 
                            ( int(getattr(item, arg, 0)) &gt; int(key_value) ) ]
            elif arg == 'lt':
                matches = [ item for item in matches if self._is_int((getattr(item, arg, None)) and 
                            ( int(getattr(item, arg, 0)) &lt; int(key_value) ) ]
        else:
            attr_value = getattr(item, key)
            if isinstance(value, str):
                if key_value.lower() == attr_value.lower():
                    matches = [ item for item in matches if 
                                ( isinstance(getattr(item,arg, None), str) and 
                                    key_value.lower() == isinstance(getattr(item,arg,"")).lower() )
                                or ( key_value == isinstance(getattr(item,arg,None)) ) ]

    return matches