Я пытаюсь оптимизировать производительность скрипта, который ищет похожие слова в лексиконе для каждого заданного слова.
Каждое уникальное слово должно быть разбито на n-граммы букв, и для каждой n-граммы лексикон возвращает список слов, содержащих одну и ту же n-грамму букв. Каждое слово из этого списка затем добавляется в словарь в качестве ключа, и его значение увеличивается на единицу. Это дает мне словарь похожих слов с соответствующими частотными показателями.
word_dict = {}
get = word_dict.get
for letter_n_gram in word:
for entry in lexicon[n_gram]:
word_dict[entry] = get(entry, 0) + 1
Эта реализация работает, но скрипт мог бы работать быстрее, заменив dict
на collections.defaultdict
.
word_dd = defaultdict(int)
for letter_n_gram in word:
for entry in lexicon[n_gram]:
word_dd[entry] += 1
Никакой другой код не был изменен.
У меня сложилось впечатление, что оба фрагмента кода (самое главное добавление очков) должны работать одинаково, т.е. если ключ существует, увеличьте его значение на 1, если он не существует, создайте ключ и установите значение равным 1.
Однако после запуска нового кода некоторые ключи имели значения 0, что я считаю логически невозможным.
Является ли моя логика или знание функциональности defaultdict
ошибочными? Если нет, то как любое значение в word_dd
может быть установлено равным 0?
редактировать: я также очень уверен, что никакая другая часть скрипта не искажает эти результаты, поскольку я проверяю словарь сразу после показанного кода, используя:
for item in word_dd.iteritems():
if item[1] == 0:
print "Found zero value element"
break
word_dd['nonesuch']
не назначает, а создает значение для вас. - person Martijn Pieters   schedule 13.04.2014defaultdict
, кажется, в порядке: код, который вы разместили, не может оказаться0 in word_dd.values()
истинным. Вы уверены, что между двумя фрагментами кода, которые вы опубликовали, нет кода, включающегоword_dd
? Кроме того, defaultdict будет работать заметно быстрее, чем dict.get/dict.setdefault, только когда значение по умолчанию дорого для вычисления, а постоянные целые числа определенно не являются. Причина, по которой стоит рассмотреть его здесь, заключается в том, что он делает ваш код проще, а не быстрее. - person lvc   schedule 13.04.2014