Что означает эта ошибка? как я могу справиться с этой ошибкой в Python? Ошибка ключа: ‘*’

#python

Вопрос:

Когда я компилирую этот код:

 import string

filename = "I:\udemy\Assignment 0.txt" # Replace with filename

# Setting up a dictionary of all ascii_lowercase letters to be incremented on each one found
amounts = {letter:0 for letter in string.ascii_lowercase }
with open(filename,'r') as file:
    # reading each line    
    for line in file:
        # reading each word        
        for word in line.split():
            amounts[word[0].lower()]  = 1 # Ignore case and increment letter counter
print(amounts)
 

Выход уже близок:

 ---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-1-89246af63302> in <module>
     10         # reading each word
     11         for word in line.split():
---> 12             amounts[word[0].lower()]  = 1 # Ignore case and increment letter counter
     13 print(amounts)

KeyError: '*' 
 

Что означает эта ошибка? как я могу справиться с этой ошибкой в Python?

 KeyError: '*'
 

Комментарии:

1. * этого нет в алфавите

2. Это означает, что вы пытаетесь заглянуть '*' в свой amounts словарь, в котором нет '*' ключа.

3. Ошибка довольно очевидна — * в dict нет ключа amounts (потому что он не является частью string.ascii_lowercase )

4. Вы можете сначала проверить, указано ли значение в суммах: if word[0].lower() in amounts: amounts[word[0].lower()] = 1

5. О да, большое вам спасибо за помощь.

Ответ №1:

Как объяснено в комментариях, KeyError означает, что вы пытаетесь получить доступ к значению, которого нет в словаре. Вы можете добавить тест, чтобы убедиться, что работаете только с буквами:

 if word[0].lower() in amounts:
    amounts[word[0].lower()]  = 1
 

Я пользуюсь возможностью продемонстрировать более эффективные/питонические способы достижения подсчета значений с помощью стандартных модулей python. В частности collections.Counter , это необходимо знать/использовать.

Вариант 1:

 import string, re
from collections import Counter

with open(filename,'r') as f:
    text = f.read()
    amount = dict(Counter([i[0].lower() for i in re.split('s ', text)
                           if i and i[0] in string.ascii_letters]))
 

Вариант 2: здесь мы используем регулярное выражение ‘b[a-zA-Z]’ для сопоставления букв в начале слов

 import re
from collections import Counter

with open(filename,'r') as f:
    text = f.read()
    amount = dict(Counter(map(str.lower, re.findall(r'(b[a-zA-Z])', text))))
 

пример ввода:

 This is An example
some words, 
for a quick  test
 

выход:

 {'t': 2, 'a': 2, 'i': 1, 'e': 1, 's': 1, 'w': 1, 'f': 1, 'q': 1}
 

Ответ №2:

Ошибка возникает, так как есть случаи, когда слово не начинается с символа, попадающего в [a-z]

решение — добавьте блок «попытка-исключение» для отладки

 try:
    amounts[word[0].lower()]  = 1
except:
    print('This ideally does not fall in [a-z]', word[0].lower())
    # If needed add the new find to amounts dictionary
    amounts[word[0].lower()] = 1
 

Комментарии:

1. Да! Большое Вам спасибо.