Home > Software engineering >  Python: Building dictionaries from csv
Python: Building dictionaries from csv

Time:11-03

I'm trying to automate some boring monkey jobs for fortigate firewalls. I receive requests to create address objects for example for 100 different hosts.. many of which should belong to same address group. My csv is

name,address,group
aix01,10.0.0.1,AIXGROUP1
aix02,10.0.0.2,AIXGROUP1
aix02,10.0.0.3,AIXGROUP2
aix245,10.0.0.4,AIXGROUP2

As you see above, there are 2x groups with 2x hosts in each.
I want to take the group names "AIXGROUP1" and "AIXGROUP2" as a dictionary keys and take list of each of the respective IPs as it's values. So, it should be {AIXGROUP1:[10.0.0.1,10.0.0.2], AIXGROUP2:[10.0.0.3,10.0.0.4]} I would then pass this dictionary to a function that prints the commands. Here's the code

with open('hosts.csv', 'r') as csvfile:
    reader = csv.reader(csvfile, delimiter = ',')
    Dictionary = {}
    for each in reader:
       if len(each[2])!=0:
          Dictionary[each[2]] = []

at this point I just have a dictionary with correct keys and empty lists as values.. and here's where I'm stuck.. how do I populate these empty lists with ip addresses? I feel like I'm inch away from the victory! :)

CodePudding user response:

You are close to a solution. The only thing you need to add is a check if the key already exist in the dictionary, so you don't overwrite it and then add a row that adds the value to the list. And you can add the row next(reader, None) if you don't want the header row in the dictionary. Something like this should work:

with open('hosts.csv', 'r') as csvfile:
    reader = csv.reader(csvfile, delimiter = ',')
    next(reader, None)  # To skip the header row
    Dictionary = {}
    for each in reader:
        if len(each[2])!=0 and each[2] not in Dictionary.keys(): # To not overwrite keys that already exist
            Dictionary[each[2]] = []
        Dictionary[each[2]].append(each[1]) #To add the values

CodePudding user response:

I would do it like this:

result = {}
for row in reader:
    if len(row[2])!=0:
        try:
            result[row[2]].append(row[1]) 
        except:
            result[row[2]] = [row[1]]
result
>>> {'AIXGROUP1': ['10.0.0.1', '10.0.0.2'], 'AIXGROUP2': ['10.0.0.3', '10.0.0.4']}

This approach creates the lists and fills them in the same loop. The try / except logic is faster than a conditional and works like this:

  1. For each row of data, try to append the address to the right group.
  2. If the exception is raised, that key doesn't yet exist in the dictionary, so we have to create it.
  3. On creating the key, we define the key as a list with one element in it, which is the current address.
  4. If the exception isn't raised, the dictionary already has one address for that key, so we just append the next one to the list referenced by that key.

Note that it's probably not best practice to name your output dict Dictionary. Also, if you are going to use csv.read(), don't forget to skip the header row!

CodePudding user response:

Your loop needs to take different actions depending on whether the group name is already in the dictionary or not, like this (I'll use d instead of Dictionary for brevity):

group = each[2]
ip = each[1]
if group in d:
    d[group].append(ip)  # Append another IP to the list
else:
    d[group] = [ip]  # Initialize list with first element

CodePudding user response:

import csv

# create the dictionary in which your data will be stored
ip_dict = {}

# open the wanted file
with open('hosts.csv', 'r') as csvfile:
    # read the csv data
    csv_reader = csv.reader(csvfile, delimiter=',')
    # skip the header
    next(csv_reader)
    # parse your data
    for _, ip, name in csv_reader:
        # do whatever you need only if name is not empty
        if name:
            # if there is already an entry in the dictionary then append to it
            if name in ip_dict:
                ip_dict[name].append(ip)
            # if there is not create a list with the current ip as the first entry
            else:
                ip_dict[name] = [ip]
  • Related