KeyError при назначении ключей и значений словаря

Недавно я начал изучать Python и хотел написать скрипт для извлечения дня месяца из столбца CSV (в формате ГГГГ/ДД/ММ), а затем сравнить пользователей веб-сайта с днями месяца (и, в конечном итоге, с неделями месяца). ) в качестве задачи/учебного упражнения. Суть в том, что он извлекает информацию из CSV, форматирует ее/преобразовывает в целые числа и объединяет обратно в словарь, сравнивая дни 1-31 с количеством посетителей сайта.

Мой код ниже. Я получаю сообщение об ошибке «KeyError: 1» в строке 29 result[days] = users. Я думаю, что понимаю, что происходит (вроде как - я предполагаю, что он недоволен тем, как я пытаюсь присвоить значения пустому словарю? Кажется, он ищет целое число 1 в качестве ключа, но не находит его? ), но я не могу понять, что делать дальше. Я изучаю Python около 2 недель, поэтому надеюсь, что это не слишком глупый вопрос. Что я делаю не так? Как я могу сделать столбцы с индексами [0] и [1] из users_by_day ключом и значением в моем словаре?

Примечание. Я изучаю и использую 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)

person Grant Hendricks    schedule 21.11.2018    source источник
comment
Строка result[days] = users не будет генерировать эту ошибку, а result[days] += users будет. Сначала убедитесь, какая строка затронута, и лучше поместите комментарий к этой строке вместо номеров строк.   -  person Michael Butscher    schedule 21.11.2018


Ответы (3)


Вызов setdefault() для словарей отлично подходит для такого рода вещей и предпочтительнее конструкции if {thing} in {dict}.

Итак, следующий код:

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

Мог стать:

result.setdefault(days, 0)
result[days] += users
person Jonah Bishop    schedule 21.11.2018
comment
Это прекрасно работает. Простой и элегантный. Я изучу функцию, чтобы понять, что она делает лучше. Ваше здоровье. - person Grant Hendricks; 21.11.2018

в части else, если в результате нет дней, уравнение, безусловно, вызовет ошибку, потому что оно использует ключ, который не завершается:

result[days] =result[days]+ users

но ты действительно имеешь в виду:

 if days is not None:
     if days not in result:     #if result doesn't have that day
         result[days] = users   #get the day and its value into result
     else:                      #if result already has the day value
         result[days] += users  #summary the value
person Lee Jack    schedule 21.11.2018

Варианты, кроме dicty.setdefault(key, val) и if key in dicty, включают:

Попробуйте/кроме

try:
    dicty[key] += value
except KeyError:
    dicty[key] = value

collections.defaultdict()

Используя collections.defaultdict():

dicty = defaultdict(int)
dicty[key] += value

Последняя строка будет выполняться с эффектом dicty[key] = value или dicty[key] += value в зависимости от ситуации (на самом деле она делает то, что если ключ не найден, запустите dicty[key] = int() перед запуском dicty[key] += value... поэтому вам нужно быть осторожным, используя это для *=).

person NotAnAmbiTurner    schedule 21.11.2018