Search code examples
pythonordereddictionary

searching for a list in a list of ordered dictionaries


So I have a list of ordered dictionaries which all have 'name' keys which take a string as a value and then a series of other keys which take integers as values. I also have a list of integers separate from the list of ordered dictionaries. I would like to search through the list of ordered dictionaries and see if there are any dictionaries which have all the integers in the list, and if so, what the 'name' value in that list is. Is there any way to do this?

I.e. i have a list of dictionaries with dictionaries like so:

dict = OrderedDict({('name' : 'John'), ('int1': 5), ('int2': 3), ('int3': 1)}), OrderedDict({('name': 'Jack'), ('int1': 1), ('int2': 6), ('int3': 7)}) 

and then a list of integers like: list = [3, 2, 5]

and if there is a match between the list and the integers in any of the ordered dictionaries, I would like to get the name returned (so in the above case, John).

This may be very basic in which case I apologise, I'm very new to python and coding in general. I've been searching for hours but I haven't found anything I can understand.


Solution

  • If I understand your question right (not that the example data, or the result for John is correct), you may be looking for

    dicts = [
        {"name": "John", "int1": 5, "int2": 3, "int3": 1},
        {"name": "Jack", "int1": 1, "int2": 6, "int3": 7},
        {"name": "Mallory", "int1": 1, "int2": 6, "int3": 3},
    ]
    
    
    def find_with_keyset(dicts, keyset):
        for dict in dicts:
            if all(
                key in dict and dict[key] == value
                for (key, value) in keyset.items()
            ):
                yield dict
    
    
    def find_first_with_keyset(dicts, keyset):
        for result in find_with_keyset(dicts, keyset):
            return result
    
    
    for match in find_with_keyset(dicts, {"int2": 6}):
        print(match["name"])
    
    print("---")
    
    print(find_first_with_keyset(dicts, {"int1": 5, "int2": 3, "int3": 1}))
    

    This prints out

    Jack
    Mallory
    ---
    {'name': 'John', 'int1': 5, 'int2': 3, 'int3': 1}
    

    The idea is that the find_with_keyset generator function filters a given iterable of dicts based on a key subset; for ease-of-use there's find_first_with_keyset which will return the first match, or None.

    To turn [1, 2, 3] to {'int1': 1, ...} you can use e.g. {f'key{i}': value for (i, value) in enumerate([1, 2, 3], 1)}.