Search code examples
pythonpython-2.7collectionsordereddictionary

search for any string value in an ordered dictionary


I have a nested ordered dictionary i.e. a ordered dictionary, some of whose values are ordered dictionary that contain further ordered dictionaries. When I use the collections module and use the following call

yOrDict = yaml_ordered_dict.load('ApplyForm.yml')

then I get an ordered dictionary yOrDict from the yml file ApplyForm.yml.

Say that yOrDict has just one key (ApplyForm) and a value which in turn is an ordered dictionary.

Further call gives another ordered dictionary:

yOrDictLevel1 = yOrDict.get('ApplyForm')

say that yOrDictLevel1 has six keys whose values contain ordered dictionaries.

say that at some place one of the ordered dictionary has a value named as Block.

Is there a call/function/method in python by which I can check if Block appears in the top level ordered dictionary - yOrDict ? i.e. I want to check if the string "Block" is at all there in yOrDict ?


Solution

  • This should do the trick.

    def find_value(needle, container):
        # Already found the object. Return.
        if needle == container:
            return True
    
        values = None
        if isinstance(container, dict):
            values = container.values()
        elif hasattr(container, '__iter__'):
            values = container.__iter__()
    
        if values is None:
            return False
    
        # Check deeper in the container, if needed.
        for val in values:
            if find_value(needle, val):
                return True
    
        # No match found.
        return False
    

    Usage:

    In [3]: d = { 'test': ['a', 'b', 'c'], 'd1': { 'd2': 'Block', 'a': 'b'} }
    
    In [4]: find_value('Block', d)
    Out[4]: True
    

    Edit: testing whether a value contains needle:

    def find_value(needle, container):
        # Already found the object. Return.
        if isinstance(container, basestring) and needle in container:
            return True
    
        values = None
        if isinstance(container, dict):
            values = container.values()
        elif hasattr(container, '__iter__'):
            values = container.__iter__()
    
        if values is None:
            return False
    
        # Check deeper in the container, if needed.
        for val in values:
            if find_value(needle, val):
                return True
    
        # No match found.
        return False