#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. Да! Большое Вам спасибо.