Home > Back-end >  Python. Problems populating a dictionary in a loop
Python. Problems populating a dictionary in a loop

Time:08-08

I am trying to add geoip information to a bunch of IP addresses I have extracted from netstat. I get my endpoint IPs in my list fine

DEBUG1: Endpoint IPs: ['165.227.118.82', '155.133.248.39', '20.54.37.64', '173.194.76.188', '74.125.206.109', '47.251.49.246', '52.19.109.21', '151.101.61.229', '151.101.60.193', '162.159.133.234', '162.159.135.232', '162.159.133.232', '162.159.129.232', '75.2.53.94', '54.170.196.176', '143.204.65.104', '34.236.20.64', '75.101.134.98', '75.101.134.98', '75.101.134.98', '52.216.249.68', '52.216.249.68', '142.250.179.228', '142.250.179.228', '52.96.165.18', '52.97.133.194', '52.98.159.194']

But when I try and enrich each of these IPs with additional information via a loop I only get the last IP returned in the dictionary. I ralise it is being over written but I cant see how or why.

Here is what happens when I run the program and I print out the resulting dictionary

DEBUG2: Enriched IP: {'IP': '52.98.159.194', 'continent': 'Europe', 'country': 'France', 'iso_code': 'FR', 'city': 'Paris', 'lat': 48.8323, 'long': 2.4075, 'timezone': 'Europe/Paris', 'accuracy': 20}

The errant function is as follows

def enrich_ip(rip):
    # ------------------This needs to be a function------------------
    # Get ip info on each of the IP's retuned in rip
    # add this information to a dictionary

    # create a dictionary to hold our ip info
    enriched_info = {}
    for ip in rip:
        # get ip info
        try:
            enriched_info['IP'] = ip
            enriched_info['continent'] = get_ip_info(ip).continent.name
            enriched_info['country'] = get_ip_info(ip).country.name
            enriched_info['iso_code'] = get_ip_info(ip).country.iso_code
            enriched_info['city'] = get_ip_info(ip).city.name
            enriched_info['lat'] = get_ip_info(ip).location.latitude
            enriched_info['long'] = get_ip_info(ip).location.longitude
            enriched_info['timezone'] = get_ip_info(ip).location.time_zone
            enriched_info['accuracy'] = get_ip_info(ip).location.accuracy_radius

        except Exception as e:
            print(e)
            continue

    return enriched_info

I pass in 'rip' to the function. rip is my list of IPs shown against DEBUG1 I had this working fine outside of a function, but I was then left with the information inside the function and not accessible elsewhere.

All help gratefully received as always

CodePudding user response:

Dictionaries cannot contain duplicate keys, that's why you only see the last IP address in resulting dictionary. Instead, create a list of dictionaries and return it:

def enrich_ip(rip):
    # ------------------This needs to be a function------------------
    # Get ip info on each of the IP's retuned in rip
    # add this information to a dictionary

    # create a list to hold our ip info
    all_data = []
    for ip in rip:
        enriched_info = {}
        try:
            enriched_info["IP"] = ip
            enriched_info["continent"] = get_ip_info(ip).continent.name
            enriched_info["country"] = get_ip_info(ip).country.name
            enriched_info["iso_code"] = get_ip_info(ip).country.iso_code
            enriched_info["city"] = get_ip_info(ip).city.name
            enriched_info["lat"] = get_ip_info(ip).location.latitude
            enriched_info["long"] = get_ip_info(ip).location.longitude
            enriched_info["timezone"] = get_ip_info(ip).location.time_zone
            enriched_info["accuracy"] = get_ip_info(ip).location.accuracy_radius

            all_data.append(enriched_info)
        except Exception as e:
            print(e)
            continue

    return all_data

Alternative would be to crate a dictionary where keys are IP:

def enrich_ip(rip):
    # ------------------This needs to be a function------------------
    # Get ip info on each of the IP's retuned in rip
    # add this information to a dictionary

    # create a dictionary to hold our ip info
    all_data = {}
    for ip in rip:
        enriched_info = {}
        try:
            enriched_info["IP"] = ip
            enriched_info["continent"] = get_ip_info(ip).continent.name
            enriched_info["country"] = get_ip_info(ip).country.name
            enriched_info["iso_code"] = get_ip_info(ip).country.iso_code
            enriched_info["city"] = get_ip_info(ip).city.name
            enriched_info["lat"] = get_ip_info(ip).location.latitude
            enriched_info["long"] = get_ip_info(ip).location.longitude
            enriched_info["timezone"] = get_ip_info(ip).location.time_zone
            enriched_info["accuracy"] = get_ip_info(ip).location.accuracy_radius

            all_data["IP"] = enriched_info
        except Exception as e:
            print(e)
            continue

    return all_data
  • Related