Как создать коллекцию из пользовательского класса в Python - PullRequest
1 голос
/ 13 марта 2019

Позвольте мне иметь следующий класс в Python:

class Word:
def __init__(self, _lemma, _frequency):
    self.lemma = str(_lemma)
    self.frequency = int(_frequency) 

Теперь я хочу создать коллекцию класса Word, которая содержит следующую логику при добавлении Word объекта word1 в коллекцию:

  • , если коллекция содержит Word объект word, где word.lemma = word1.lemma, тогда word.frequency = word.frequency + word1.frequency
  • еще добавить word1 в коллекцию

Как я могу это сделать?


Ранее я использовал для этого список, где я проверял, содержит ли список объект Word, который имеет lemma с word1.lemma. Но у подхода есть O (n ^ 2) сложность, чтобы добавить n word в коллекцию.

from Word import Word

class Corpus:

    def __init__(self, _name, _total_count):
        self.name = str(_name)
        self.total_count = int(_total_count)
        self.words = []

    def add(self, _word):

        find_word = [index for index, word in enumerate(self.words) if word.lemma == _word.lemma]  # O(n)
        if len(find_word) == 0:
            self.words.append(Word(_word.lemma, _word.frequency))
        else:
            self.words[find_word[0]].frequency = self.words[find_word[0]].frequency + _word.frequency

Ответы [ 2 ]

3 голосов
/ 13 марта 2019

Вы можете легко это сделать, используя словарь вместо списка, используя в качестве ключа word.lemma:

def add(self, _word):
    if _word.lemma not in self.words:
        self.words[_word.lemma] = _word
    else:
        self.words[_word.lemma].frequency += _word.frequency

неудобно, что она дублирует информацию о лемме ...


Если использование класса Word не является обязательным, вы можете использовать defaultdict (со значением по умолчанию 0), которое просто связывает частоту (значение) с леммой (ключом):

class Corpus:
    def __init__(...):
        ...
        self.words = defaultdict(lambda: 0)

    def add(self, lemma, frequency):
        self.words[lemma] += frequency
2 голосов
/ 13 марта 2019

Ваша формулировка может сбить с толку членов сообщества, знакомых с Python.Я думаю, что вы используете термин «словарь» как часть модели вашего домена, а не как структуру данных в Python.

Если вам действительно нужны классы Word и Corpus - вы должны продолжитькод вроде этого:

from collections import defaultdict


class Word:

    def __init__(self, lemma: str, frequency: int):
        self.lemma = lemma
        self.frequency = frequency

    def __eq__(self, other):
        return self.lemma == other.lemma

   def __hash__(self):
       return hash(self.lemma)


class Corpus:

    def __init__(self):
        self.words = defaultdict(0)

    def add(self, word: Word):
        self.words[word] += word.frequency

Ключевые моменты:

  1. Использование подсказок типа
  2. Как dict поиск (например, 'b' in {'a': 23, 'b': 24}) работает - Когда __eq__ вызывается с использованием hash ()?
  3. defaultdict использование
  4. __eq__ и __hash__ использование

И я настоятельно рекомендую подумать, действительно ли вы хотите хранить Word экземпляров в Corpus.

...