"Открытые" словарные ключи? (LPTHW упражнение 48 связано)
Я работаю над упражнением 48 Изучить Python The Hard Way и пишу lexicon
словарь и scan
модуль для запуска следующего теста:
from nose.tools import *
from ex47 import lexicon
def test_directions():
assert_equal(lexicon.scan("north"), [('direction', 'north')])
result = lexicon.scan("north south east")
assert_equal(result, [('direction', 'north'),
('direction', 'south'),
('direction', 'east')])
def test_verbs():
assert_equal(lexicon.scan("go"), [('verb', 'go')])
result = lexicon.scan("go kill eat")
assert_equal(result, [('verb', 'go'),
('verb', 'kill'),
('verb', 'eat')])
def test_stops():
assert_equal(lexicon.scan("the"), [('stop', 'the')])
result = lexicon.scan("the in of")
assert_equal(result, [('stop', 'the'),
('stop', 'in'),
('stop', 'of')])
def test_nouns():
assert_equal(lexicon.scan("bear"), [('noun', 'bear')])
result = lexicon.scan("bear princess")
assert_equal(result, [('noun', 'bear'),
('noun', 'princess')])
def test_numbers():
assert_equal(lexicon.scan("1234"), [('number', 1234)])
result = lexicon.scan("3 91234")
assert_equal(result, [('number', 3),
('number', 91234)])
def test_errors():
assert_equal(lexicon.scan("ASDFADFASDF"), [('error', 'ASDFADFASDF')])
result = lexicon.scan("bear IAS princess")
assert_equal(result, [('noun', 'bear'),
('error', 'IAS'),
('noun', 'princess')])
Я с этим большей частью разобрался, кроме цифр и ошибок тестов. Когда пользовательский ввод - это слово, которое не определено в словаре, оно должно быть помечено error
имя значения, а если это число - number
Имя значения. Очевидно, что я могу предварительно добавить все входные данные, которые будут проверены в словаре, но это обман.
мой словарь выглядит так:
lexicon = {
'north': 'direction',
'princess': 'noun',
# etc...
}
Есть ли способ включить в него "открытые" определения для чисел и неопределенных слов?
ОБНОВИТЬ. Вот рабочее решение:
def scan(sentence):
words = sentence.split()
pairs = []
for word in words:
try:
number = int(word)
tupes = ('number', number)
pairs.append(tupes)
except ValueError:
try:
word_type = lexicon[word]
tupes = (word_type, word)
pairs.append(tupes)
except KeyError:
tupes = ('error', word)
pairs.append(tupes)
return pairs
2 ответа
Я думаю, что вы найдете эту "открытость", проверив, есть ли ваш элемент в словаре. Примерно так будет работать:
my_item in lexicon
Возвращает True, если словарь lexicon
содержит ключ my_item
и Ложь в противном случае.
Но есть лучший способ сделать это.
Это хорошая возможность попрактиковаться в концепции Python "Лучше просить прощения, чем разрешения". Как насчет чего-то вроде:
try:
value = lexicon[my_item]
except KeyError:
# KeyError is thrown when you index into a dictionary with a nonexistent key
value = 'error'
По совпадению, вы можете сделать то же самое, чтобы проверить, можно ли преобразовать строку в целое число.
try:
value = int(maybe_a_number)
except ValueError:
# maybe_a_number wasn't a number!
Это обычный шаблон в Python - попробуйте использовать переменную определенным образом и обработать случай сбоя.
Дополнительную информацию о словарях можно найти по адресу: http://docs.python.org/2/library/stdtypes.html.
Вы можете использовать метод get словаря с необязательным аргументом по умолчанию:
d = {"a":'letter', 4:'number'}
result = d.get("not in d", 'error')
print result
# error
В python также распространено использование циклов try/ Кроме того, чтобы проверять наличие ключевых ошибок, хотя в этом случае это, вероятно, излишне.
d = {"a":'letter', 4:'number'}
try:
result = d['not in d']
except KeyError:
result = 'error'
print result
# error
Я думаю, что самый простой способ проверить, является ли строка числом в python, - это использовать либо float, либо int внутри блока try кроме блока, во многом как во втором примере выше. Какой из них вы используете, будет зависеть от того, хотите ли вы считать "1.2" и "3.4e5" числами или нет.