Home > OS >  How to catch keyerror and execute the rest of code if keyerror equals to zero
How to catch keyerror and execute the rest of code if keyerror equals to zero

Time:03-18

I am trying to write a function that checks if the given variable is country name, city name, or some rubbish word. first I check if the variable is the country name. for that, I use an API. If the variable is not in the list of the country names I want to check it in the cities name list. The problem is that if the variable name does not exist it return a key error : 0 error and I cannot move to pass that and insert my city name checking code. Is there any way to get around this? This is what I have tired

def searchCountry():
    try:
        address = 'berlin'
        checkcountry = 'https://restcountries.com/v3.1/name/'   address 
        json_data = requests.get(checkcountry).json()
        new_address  = json_data[0]['name']['common']
    except KeyError as e:
        try:
            if e == 0:
                checkcities =  'https://countriesnow.space/api/v0.1/countries'
                json_data = requests.get(checkcities).json()
                cities_list = []
                for i in range(0,len(json_data['data'])):
                    list = json_data['data'][i]['cities']
                    cities_list.append(list)
                new_list=sum(cities_list, [])
                for item in new_list:
                    if address == item:
                        return address
                    else:
                        print('error')
        except:
            pass

CodePudding user response:

While it's not guaranteed from other types reusing it, dict generated KeyErrors pass the missing key as the sole argument to the constructor for KeyError, and like all exceptions, it stores its arguments as a tuple in the .args attribute. So all you need to do is replace:

if e == 0:

with:

if e.args[0] == 0:
# Or to be absolutely sure it wasn't constructed with additional arguments:
if e.args == (0,):  # Trailing comma mandatory to make it an actual one-tuple

CodePudding user response:

There is a bunch of cleanup we can do to guard against ever running into the key error using get(). While we are at it, let's also query the country/city API once and get all the data and cache it so that repeated requests are faster.

This technique is often called a closure.

import requests

## -------------------------------
## Use a closure to fetch and cache coutry/city data
## -------------------------------
def build_country_searcher():
    checkcities =  'https://countriesnow.space/api/v0.1/countries'
    response = requests.get(checkcities)

    if not response.ok:
        raise Exception("failed to fetch data")

    ## -------------------------------
    ## Construct lookups for counties and cities once and cache results
    ## -------------------------------
    countries = set()
    city_to_country = {}
    for country in response.json().get("data", []):
        country_name = country["country"]

        countries.add(country_name)

        for city in country["cities"]:
            city_to_country.setdefault(city, []).append(country_name)
    ## -------------------------------

    ## -------------------------------
    ## hidden utility function to just look up if the given name
    ## is a country. Note, we could also have used the abo
    ## -------------------------------
    def check_country(name):
        return name if name in countries else None
    ## -------------------------------

    ## -------------------------------
    ## Note that a city could be found in many countries so for
    ## fun, let's return those counties as a comma separated list.
    ## -------------------------------
    def check_city(name):
        return ", ".join(city_to_country.get(name, []))
    ## -------------------------------

    ## -------------------------------
    ## return our function that will process the lookups.
    ## -------------------------------
    return lambda name: check_country(name) or check_city(name) or None
    ## -------------------------------
## -------------------------------

## -------------------------------
## Build out search function
## -------------------------------
country_searcher = build_country_searcher()
## -------------------------------

print(country_searcher("Germany"))
print(country_searcher("Berlin"))
print(country_searcher("Middle Earth"))

This should give you back:

Germany
Germany, United States
None
  • Related