Текст класса в Python


Вот это класс Text, который принимает строку в качестве аргумента конструктора. Оно имеет свойство-методы, чтобы получить слова в строке, а также частота алфавитов, встречающихся в нем.

В words собственность в результате все слова в строке. Он работает следующим образом, после использования .split способ, есть вероятность, что "слово" имеет форму ,word или word. или ,word. и т. д. Так, чтобы столкнуться с этим мы проверяем каждого конца, используя .isalpha.

У нас тоже есть find_words метод, в котором есть слова как ее входы. Этот метод суммирования частот из набора слов.

Как я могу написать это лучше:

  • Уровень библиотека/пакет (я не очень понимаю технику для этого)
  • Более эффективным и читабельным (используя re модуль-это последний вариант)
  • Более функциональный, но компактный

#Author: Arief. A

example = "This is an example, an Anonymous text.\
 This text has 59 letters or numbers.";


class Text:

    def __init__(self, input_text):
        self.text = input_text;

    def show(self):
        print(self.text);

    def as_list(self):
        return list(self.text);

    def get_length(self):
        return len(self.text);

    def count_char(self, char):
        return self.text.count(char);

    @property          
    def letter_freqs(self):
        letters="abcdefghijklmnopqrstuvwxyz";
        res={i: self.count_char(i) \
             for i in letters};
        caps={i.capitalize(): self.count_char(i.capitalize()) \
             for i in letters};
        res.update(caps);
        return res

    @property   
    def words(self):
        raw=self.text.split();
        for i in range(len(raw)):
            if not raw[i][0].isalpha():
                raw[i]=raw[i][1:];
            if not raw[i][-1].isalpha():
                raw[i]=raw[i][0:-1];
        [raw.remove('') for i in range(raw.count(''))];
        return raw            

    def swap_first(word):
        swaped=word[0].swapcase();
        res=swaped+word[1:];
        return res

    def find_words(self, *args):
        return {i: self.words.count(i)\
                      +self.words.count(Text.swap_first(i))\
                      for i in args};

Пример

text_obj=Text(example);
text_obj.show();
print(text_obj.as_list());
print(text_obj.get_length());
print(text_obj.count_char("a"));
print(text_obj.words)
print(text_obj.find_words("Anonymous", "Text","This"));

Выход

This is an example, an Anonymous text. This text has 59 letters or numbers.
['T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', 'n', ' ', 'e', 'x', 'a', 'm', 'p', 'l', 'e', ',', ' ', 'a', 'n', ' ', 'A', 'n', 'o', 'n', 'y', 'm', 'o', 'u', 's', ' ', 't', 'e', 'x', 't', '.', ' ', 'T', 'h', 'i', 's', ' ', 't', 'e', 'x', 't', ' ', 'h', 'a', 's', ' ', '5', '9', ' ', 'l', 'e', 't', 't', 'e', 'r', 's', ' ', 'o', 'r', ' ', 'n', 'u', 'm', 'b', 'e', 'r', 's', '.']
75
4
['This', 'is', 'an', 'example', 'an', 'Anonymous', 'text', 'This', 'text', 'has', 'letters', 'or', 'numbers']
{'This': 2, 'Text': 2, 'Anonymous': 1}


608
5
задан 22 февраля 2018 в 02:02 Источник Поделиться
Комментарии
3 ответа


  • Вместо letters="abcdefghijklmnopqrstuvwxyz"; использовать встроенные константы:

    letters = string.letters;

  • Код проверяет только первый и последний символ слова. Это означает, что aaa.bbb будет рассматриваться как одно слово. Это намерение?

  • split(sep) позволяет строку разделителей. Назвав его с

    raw = self.text.split(string.punctuation + string.whitespace)

    исключает необходимость проверки отдельных слов. Если вы все еще хотите, чтобы проверить их, петли for i in range(len(raw)): должно быть написано более идиоматически как

    for word in raw:

    (вы действительно не нужно i в любой точке петли).


3
ответ дан 22 февраля 2018 в 05:02 Источник Поделиться

Это я считаю, что ООН-подходящие для Python:

class Text:

def as_list(self):
return list(self.text);

def get_length(self):
return len(self.text);


Вы пишете методов класса, которые используют банальные примитивы, но экземпляр себя поведет себя совершенно иначе, когда вы вызываете len, респ. list на нем.

Кроме того, класс в основном реализует текст, который может быть рассмотрен случай особенный строки.
Так почему бы не расширить его оттуда:

class Text(str):

def show(self):
print(self);

def count_char(self, char):
return self.count(char)

Вы можете получить список и длина тогда по телефону list(text_instance), респ. len(text_instance).

Можно упростить letter_freqs способ использования string.ascii_letters:

    @property          
def letter_freqs(self):
return {i: self.count_char(i) for i in string.ascii_letters}

def find_words(self, *args):
return {i: self.words.count(i) + self.words.count(
Text.swap_first(i)) for i in args}

Некоторые другие вещи:


  1. Вам не нужно точки с запятой в конце операторов в Python.

  2. Обратные линии разрыва не требуется в скобки, скобках и, следовательно, не требуется в дикт списочные.

  3. В swap_first функция не является ни метод, ни метод класса и, следовательно, должны быть определены на уровне модуля.

  4. Документ ваш класс и методов, используя комментарии.

  5. Советуем также ознакомиться с PEP8.

Также попробуйте переписать ваш words собственность. Он не ведет себя надежно, например, на такую тему 'He shot him with a .45.'

0
ответ дан 26 февраля 2018 в 12:02 Источник Поделиться

Мне нравится общее содержание в других ответов, так что я просто добавить мои 2 цента.

Кэш свойств

Нет необходимости, чтобы бессмысленно повторить операции со строками каждый раз; просто кэшировать и расчета по требованию.

Использовать collections.Counter

Вы делаете гистограммы; что имеет встроенную поддержку

from collections import Counter
_counter = None
@property
def letter_freqs(self):
if self._counter is None:
self._counter = Counter(letter for letter in self.text if self.meets_filter(letter))
return self._counter

Можно реализовать self.meets_filter довольно тривиально (letter.lower() in string.ascii_lowercase, например), и даже в он-лайн, если у вас нет более сложную логику.

Вы можете также применить Counter на ваши слова список тоже.

def find_words(self, *args):
return Counter(word for word in self.words
if word in args or Text.swap_first(word) in args))

Ты не отвечаешь что-то "сырое", так что не называй это так

Кроме того, вы можете намного упростить и исправить ошибку уже упоминалось, при плохой текст.

import re

_words = None
@property
def words(self):
if self._words is None:
self._words = [re.sub(r"[_\d\W]", '', word) for word in self.text.split()]
return self._words

Прекратить использование точки с запятой

Пожалуйста.

0
ответ дан 26 февраля 2018 в 12:02 Источник Поделиться