Объединение мультимножества javaCode в python (в диапазоне)

У меня проблемы с преобразованием класса Multiset из java в Python. У меня особая проблема с этим этот фрагмент Java-кода для Python:

public Multiset unionWith(Multiset other)
{
    Multiset result = new Multiset();

    for ( Object object : elts.keySet() )
    {
        for ( int i = 0; i != elts.get(object); ++i )
        {
            result.add(object);
        }
    }

    for ( Object object : other.elts.keySet() )
    {
        for ( int i = 0; i != other.elts.get(object); ++i )
        {
            result.add(object);
        }
    }

    return result;
}

}

Это весь созданный мною Класс. Кажется, все работает, кроме unionWith, чего я не могу понять. Я почти уверен, что проблема с 'in range', с условием. Как это работает в Python?

class Multiset:
def __init__(self):
   self.elts= dict()

def contains(self, o):
    if o in self.elts.keys():
        return True
    else:
        return False

def add(self, o):
    if self.contains(o):
        newValue = self.elts.get(o) + 1
        self.elts[o] = newValue
    else:
        self.elts[o] = 1

def remove(self, o):
    if self.contains(o):
        newValue = self.elts.get(o) - 1

        if newValue > 0:
            self.elts[o] = newValue
        else:
            del self.elts[o]


def elements(self):
    return set(self.elts.keys())
@property
def size(self):
    total = 0

    for object in self.elts.values():
        total = total + self.elts.get(object)

    return total
def unionWith(self,other):
    result= Multiset()

    for object in self.elts.values():

        for i in range(0):
            if i is not self.elts.get(object):
                break
            result.add(object)

    for object in other.elts.values():
        for i in range(0):
            if i is not other.get(object):
                break
            result.add(object)

У меня такое ощущение, что вы пишете for i in range(0): с намерением, что он должен означать «итерацию вверх с нуля бесконечно», но это не то, что он делает. Что он делает: «перебирает все значения от 0 (включительно) до 0 (исключая)». Если вы хотите бесконечно перемещаться вверх от нуля, попробуйте itertools.count.

Kevin 19.07.2018 14:45
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
49
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я предлагаю вам использовать волшебные методы, чтобы сделать ваш класс более интегрированным с языком Python, например __iter__ и __contains__:

import collections
import itertools

class Multiset:
    def __init__(self, iterable=None):
        self._data = collections.defaultdict(int)
        if iterable:
            self._data.update(collections.Counter(iterable))

    def __contains__(self, element):
        return element in self._data

    def add(self, element):
        self._data[element] += 1

    def remove(self, element):
        if element not in _data:
            raise KeyError(element)
        elif self._data[element] == 1:
            del self._data[element]
        else:
            self._data[element] -= 1

    def update(self, iterable):
        data = collections.Counter(self._data) + collections.Counter(iterable)
        self._data = collections.defaultdict(int)
        self._data.update(data)

    def elements(self):
        return self._data.keys()

    def __len__(self):
        return sum(self._data.values())

    def __iter__(self):
        return itertools.chain.from_iterable(
            itertools.repeat(element, number) 
                for element, number in self._data.items()
        )

    def union(self, other):
        result = Multiset(self)
        result.update(other)
        return result

    def __repr__(self):
        return 'Multiset([{}])'.format(
            ', '.join(repr(element) for element in self))

Тестирование:

>>> s = Multiset()
>>> s
Multiset([])
>>> s.update('abca')
>>> s
Multiset(['a', 'a', 'c', 'b'])
>>> len(s) # calls __len__
>>> 'a' in s  # calls __contains__
True
>>> r = Multiset('zxc')
>>> r
Multiset(['x', 'c', 'z'])
>>> s.union(r)
Multiset(['a', 'a', 'x', 'c', 'c', 'b', 'z'])

Могло быть реализовано больше, например __add__, __sub__ (разница), intersection ...

Другие вопросы по теме