Search code examples
pythonpython-3.xfuzzy-searchfuzzywuzzy

Fuzzywuzzy for a list of dictionaries


I have a list of dictionaries (API response) and I use the following function to search for certain nations:

def nation_search(self):
    result = next((item for item in nations_v2 if (item["nation"]).lower() == (f"{self}").lower()), False)
    if result:
        return result
    else:
        return next((item for item in nations_v2 if (item["leader"]).lower() == (f"{self}").lower()), False)

2 examples :

nations_v2 = [{'nation_id': 5270, 'nation': 'Indo-Froschtia', 'leader': 'Saxplayer', 'continent': 2, 'war_policy': 4, 'domestic_policy': 2, 'color': 15, 'alliance_id': 790, 'alliance': 'Rose', 'alliance_position': 3, 'cities': 28, 'offensive_wars': 0, 'defensive_wars': 0, 'score': 4945, 'v_mode': False, 'v_mode_turns': 0, 'beige_turns': 0, 'last_active': '2020-08-10 04:04:48', 'founded': '2014-08-05 00:09:31', 'soldiers': 0, 'tanks': 0, 'aircraft': 2100, 'ships': 0, 'missiles': 0, 'nukes': 0},
{'nation_id': 582, 'nation': 'Nightsilver Woods', 'leader': 'Luna', 'continent': 4, 'war_policy': 4, 'domestic_policy': 2, 'color': 10, 'alliance_id': 615, 'alliance': 'Seven Kingdoms', 'alliance_position': 2, 'cities': 23, 'offensive_wars': 0, 'defensive_wars': 0, 'score': 3971.25, 'v_mode': False, 'v_mode_turns': 0, 'beige_turns': 0, 'last_active': '2020-08-10 00:22:16', 'founded': '2014-08-05 00:09:35', 'soldiers': 0, 'tanks': 0, 'aircraft': 1725, 'ships': 115, 'missiles': 0, 'nukes': 0}]

I want to add a fuzzy-search using fuzzywuzzy to get 5 possible matches in case there's a spelling error in the argument passed into the function but I can't seem to figure it out.

I only want to search in values for nation and leader.


Solution

  • If you need 5 possible matches, use process.

    from fuzzywuzzy import process
    
    def nation_search(self):
        nations_only = [ v2['nation'].lower() for v2 in nations_v2 ]
        leaders_only = [ v2['leader'].lower() for v2 in nations_v2 ]
    
        matched_nations = process.extract((f"{self}").lower(), nations_only, limit=5)
        matched_leaders = process.extract((f"{self}").lower(), leaders_only, limit=5)
    
        return matched_nations, matched_leaders