@quintbrut

Как можно оптимизировать данный код?

В общем дорабатываю snоwbаll.
Вот что у меня получилось.
sb.py
#Snоwball_kаzаk
#MB_Edited_v.1.3

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
The Snowball stemmer.
"""

import re
import unittest


class Stemmer:
    # Helper regex strings.
    _vowel = "[аәоөұүыіеиуёэюя]"
    _non_vowel = "[^аәоөұүыіеиуёэюя]"

    # Word regions.
    _re_rv = re.compile(_vowel)
    _re_r1 = re.compile(_vowel + _non_vowel)

    # Endings.

    _re_all = re.compile(
        r"(шалық|шелік|даған|деген|таған|теген|лаған|леген|"
	r"дайын|дейін|тайын|тейін|"
        r"ңдар|ңдер|дікі|тікі|нікі|атын|етін|йтын|йтін|"
	r"гелі|қалы|келі|ғалы|шама|шеме|"
	r"мын|мін|бын|бін|пын|пін|мыз|міз|быз|біз|пыз|піз|сың|сің|"
	r"сыз|сіз|ңыз|ңіз|дан|ден|тан|тен|нан|нен|нда|нде|дың|дің|тың|"
	r"тің|ның|нің|дар|дер|тар|тер|лар|лер|бен|пен|мен|"
	r"дай|дей|тай|тей|дық|дік|тық|тік|лық|лік|паз|"
	r"ғыш|гіш|қыш|кіш|шек|шақ|шыл|шіл|нші|ншы|дап|деп|"
	r"тап|теп|лап|леп|даc|деc|таc|теc|лаc|леc|ғар|гер|қар|кер|дыр|"
	r"дір|тыр|тір|ғыз|гіз|қыз|кіз|ған|ген|қан|кен|"
	r"ушы|уші|лай|лей|сын|сін|бақ|бек|пақ|пек|мақ|мек|йын|йін|йық|йік|"
	r"сы|сі|да|де|та|те|ға|ге|қа|ке|на|не|"
	r"ді|ты|ті|ны|ні|ды|ба|бе|па|пе|ма|ме|"
	r"лы|лі|ғы|гі|қы|кі|ау|еу|ла|ле|ар|ер|"
	r"ып|іп|ша|ше|са|се|"
        r"лақ|лық|"
	r"н|р|п|й|ы|і)$"
    )

    def stem(self, word):
        """
        Gets the stem.
        """

        rv_pos, r2_pos = self._find_rv(word), self._find_r2(word)

        word1 = self._step_1(word, r2_pos)

        while word1 != word:
            word = word1
            word1 = self._step_1(word, r2_pos)
        
        return word1

    def _find_rv(self, word):
        """
        Searches for the RV region.
        """

        rv_match = self._re_rv.search(word)
        if not rv_match:
            return len(word)
        return rv_match.end()

    def _find_r2(self, word):
        """
        Searches for the R2 region.
        """

        r1_match = self._re_r1.search(word)
        if not r1_match:
            return len(word)
        r2_match = self._re_r1.search(word, r1_match.end())
        if not r2_match:
            return len(word)
        return r2_match.end()

    def _cut(self, word, ending, pos):
        """
        Tries to cut the specified ending after the specified position.
        """

        match = ending.search(word, pos)
        if match:
            try:
                ignore = match.group("ignore") or ""
            except IndexError:
                # No ignored characters in pattern.
                return True, word[:match.start()]
            else:
                # Do not cut ignored part.
                return True, word[:match.start() + len(ignore)]
        else:
            return False, word
    
    def _step_1(self, word, r_pos):
        _, word = self._cut(word, self._re_all, r_pos)
        return word


class TestStemmer(unittest.TestCase):
    """
    Tests the stemmer.
    """
    _stemmer = Stemmer()
    
    def test_stem(self):

        with open("diffs-kazak.txt", "rt", encoding="utf-8") as diffs_file:
            diffs = diffs_file.readlines()
        for i, line in enumerate(diffs):
            word, stem = line.split()
            self.assertEqual(
                stem,
                self._stemmer.stem(word),
                "Diff in word: %s (%d/%d)" % (word, i + 1, len(diffs)),
            )


if __name__ == "__main__":
    sourceFile = open('about.txt',encoding='utf-8')
    for line in sourceFile:
        w1 = line
        if w1[-1] == "\n":
            w_about = w1.replace('\n', '')
        else:
            w_about = w1
        
        print(w_about)
    sourceFile.close()
    print("\n Сейчас программа работает. Программа автоматический завершит свою работу по окончании всех задач.")  






    stemmer = Stemmer()
    f1 = open("first.txt",mode = 'r',encoding = 'utf-8') #Тут исходный файл для обработки
    for line in f1:
        word1 = (line)
        word = str(word1)
        word = stemmer.stem(word)
        
        #Очистим от пустых строк
        if word[-1] == "\n":
            new_word = word.replace('\n', '')
        else:
            new_word = word
        #Теперь надо очистить мусор (пока что, все кроме слов)
        if new_word.isalpha():
            w2 = new_word
        else:
            continue
        #Теперь надо очистить все русские слова
        flag = True
        wdel = []
        with open("base.txt", encoding = 'utf-8') as f2:
            for line in f2:
                if w2 in line:
                    wdel.append(w2)
                    flag = False
            if flag:
                w3 = w2
            else:
                with open('deleted.txt', 'a', encoding = 'utf-8') as d: #Это необъязательный пункт, своебразная корзина
                    d.write('\n'.join(set(wdel)) + "\n")
        ffinal = open("good.txt",mode = 'a',encoding = 'utf-8') #Запись результата после обработки ведется в этот файл
        try:#В этом  блоке нужно выделить изменившиеся слова.
            if word == w3:
                ffinal.write(w3 + "\n") #Измененное слово записывается в измененном виде
            else:
                ffinal.write(w3 + " +\n") #НеИзмененное слово записывается с постфиксом "+"


            
            
        except:
            continue
        del(w3)


В файле base.txt все русские слова
В файле
first.txt
баскарды
балқарлардан
Балқарларды
Кабардин
азшылықтарын
Отандарынан
дауылынан
концлагерьлерде
азаппен
жұмуы
демограф
карқыны
шакырылды
аттанғандар
Сондай-ак
колонналарына
шығыска
все слова что нужно провести через программу.

Теперь вопрос, как можно оптимизировать данный код, чтобы он работал быстрее? А именно процесс записи и отчистки, это последние строчки кода. Я уверен что более умелые программисты сразу заметят, где и как можно укоротить и оптимизировать. Спасибо. Пока учусь.
  • Вопрос задан
  • 88 просмотров
Пригласить эксперта
Ответы на вопрос 2
@gimntut
Очевидно, что причина торможения из-за открытия и закрытия файлов base.txt, deleted.txt и good.txt для каждой строчки из first.txt.
Должно быть как-то так:
f2 = open("base.txt", encoding = 'utf-8')
d = open('deleted.txt', 'a', encoding = 'utf-8')
ffinal = open("good.txt",mode = 'a',encoding = 'utf-8')
f1 = open("first.txt",mode = 'r',encoding = 'utf-8')
for line in f1:
   ...
f1.close()
ffinal.close()
d.close()
f2.close()
Ответ написан
dimonchik2013
@dimonchik2013
non progredi est regredi
мало кода

кстати, для
w1.replace('\n', '')
придумали
w1.strip()

продолжайте учиться
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
23 нояб. 2024, в 01:31
1000 руб./за проект
23 нояб. 2024, в 00:16
2000 руб./за проект
22 нояб. 2024, в 23:55
3000 руб./за проект