- делает данные
collections.Counter
или defaultdict
вместо списка (поскольку вам строго не важна последовательность битов, учитывается только количество их появлений) - затем
update
ваш self.counts[item]
со счетчиком вместо назначения dict - вы могли бы даже выполнить обновление прямо:
for item in ngrams:
data = self.counts[item]
for word in findall( item+".", text):
data[word[-1]] += 1
, и это все, это обновит релевантные подсчеты прямо в defaultdict, как первоначально определено
То, что большая часть кода ... не идеальна или нечетна
кажется излишне сложным
Вы получаете каждый код после ngram, почему бы просто не извлечь псевдонграммы n + 1 и разбить это? Что-то вроде (непроверенное, может быть немного не так):
for i in range(0, len(text)-n):
ngram, follower = text[i:i+n], text[i+n]
self.counts[ngram][follower] += 1
Это также позволяет избежать по меньшей мере квадратичной c сложности вашего кода (и различных постоянных сложностей), что является хорошей стороной -эффект, хотя обратите внимание, что оригинал неявно пропускает последователей \n
(перевод строки / новой строки), так как re.DOTALL
, .
"соответствует любому символу, кроме новой строки". Поэтому, если вы хотите сохранить такое поведение, вам придется специально проверить и пропустить follower == '\n'
.
Повторное использование переменных-членов в качестве локальных?
Вы по какой-то странной причине повторно используете self.counts
в качестве локальной переменной, сохраняя ее в out
, устанавливая ее в странные вещи, а затем перезагружая после того, как вы установили его на себя, почему бы не out
внутренняя переменная?
for item in ngrams:
data = []
for word in findall( item+".", text):
data.append(word[-1])
out = { item : data.count(item) for item in data }
self.counts[item] = out
Не то, чтобы это было очень полезно (возможно, кроме утилиты отладки printf), вы могу присвоить self.counts[item]
прямой.
Я также понятия не имею, какие утилиты __starting_text
и __charas
имеют
двойные префиксы подчеркивания
Не. Неважно, для чего вы их используете, я вполне уверен, что вы не правы (потому что я редко сталкивался с людьми, которые знали, для чего они нужны), и вы должны прекратить это.
Если Вы хотите, чтобы вызывающие стороны намекали, что что-то является внутренней деталью объекта, используйте один префикс подчеркивания. Хотя вам, вероятно, и этого делать не нужно.
всегда передают кодировку в текстовый режим open
Серьезно. open(path)
работает в текстовом режиме (автоматически декодирует необработанные данные на диске в str
), но кодировка, которую он выбирает, - это то, что возвращает getdefaultencoding()
, что, скорее всего, не является мусором. Вы не хотите использовать его для чтения файла пользователя, и вы действительно абсолютно никогда не хотите использовать его для чтения вашего собственного файла. Явно предоставьте encoding='utf-8'
, это позволит избежать большого горя в будущем. Если вам нужно вывести кодировку , возможно , используйте chardet.