Search code examples
pythonpython-3.xcsvdictionarykeyerror

KeyError When Assigning Dictionary Keys and Values


I've recently begun learning Python and I wanted to write a script to extract the day of the month from a CSV column (formatted as YYYY/DD/MM) then compare website users to days of the month (and eventually weeks of the month) as a challenge/learning exercise. The gist is that it extracts the CSV info, formats it/converts to integers, and smushes it back together as a dictionary comparing days 1-31 with the number of site visitors.

My code is below. The error I'm receiving is 'KeyError: 1'on line 29 result[days] = users. I think I understand what is happening (kind of - I'm guessing it's not happy with the way I'm trying to assign values to an empty dictionary? It seems to be looking for the integer 1 as a key but not finding it?) but I can't figure out what to do next. I'm about 2 weeks into learning Python so I hope this isn't too stupid a question. What am I doing wrong? How can I make the columns at index [0] and [1] of users_by_day the key and value in my dictionary?

Note: I am learning and using Python 3.

 import csv
 result = {}
 with open('analytics.csv') as csv_file:
     csv_reader = csv.reader(csv_file, delimiter=',')
     line_count = 0
     users_by_day = list(csv_reader)
     for row in users_by_day: #iterate through data

          day = row[0].split('/') #split date to extract day of month

         try: #skip unsplit cells

             day = day[1]
         except Exception as e:
             pass
         row[0] = day #set list column to extracted day value

 users_by_day = users_by_day[1:-1] #strip headers

 for row in users_by_day:
     days = None
     users = None

         days = int(row[0]) #set values to int for math
         users = int(row[1])

     if days is not None:
         if days in result: #trying to check for days in result
             result[days] = users #where key error occurs
         else:
             result[days] += users

 print(result)

Solution

  • The setdefault() call on dictionaries is great for this kind of thing, and is preferable to the if {thing} in {dict} construct.

    So the following code:

    if days in result:  # trying to check for days in result
        result[days] = users  # where key error occurs
    else:
        result[days] += users
    

    Could become:

    result.setdefault(days, 0)
    result[days] += users