Я бы не стал создавать подклассы set
, поскольку очевидно, что вы не сможете использовать повторно ни одну часть реализации set
. Я бы даже не стал создавать подклассы collections.Set
, поскольку последний требует от вас предоставить __len__
- функциональность, которая, как вам кажется, не нужна в противном случае, и просто не может быть эффективно выполнена в общем случае (это будет O(N)
, с, размер которого вы говорите, слишком медленный). Вам вряд ли удастся найти какую-либо существующую реализацию, которая достаточно хорошо соответствует вашему варианту использования, чтобы ее можно было использовать повторно, потому что ваши требования очень специфичны и даже своеобразны - например, концепция «случайной итерации и случайного дублирования в порядке» действительно необычный.
Если ваши спецификации завершены (вам нужны только объединение, пересечение и случайная итерация, а также случайные добавления и удаления отдельных элементов), реализация класса специального назначения, который заполняет эти спецификации, не является сумасшедшей задачей. Если у вас есть больше спецификаций, которые вы явно не упомянули, это будет сложнее, но трудно угадать, не услышав все спецификации. Так, например, что-то вроде:
import random
class AbSet(object):
def __init__(self, predicate, maxitem=1<<32):
# set of all ints, >=0 and <maxitem, satisfying the predicate
self.maxitem = maxitem
self.predicate = predicate
self.added = set()
self.removed = set()
def copy(self):
x = type(self)(self.predicate, self.maxitem)
x.added = set(self.added)
x.removed = set(self.removed)
return x
def __contains__(self, item):
if item in self.removed: return False
if item in self.added: return True
return (0 <= item < self.maxitem) and self.predicate(item)
def __iter__(self):
# random endless iteration
while True:
x = random.randrange(self.maxitem)
if x in self: yield x
def add(self, item):
if item<0 or item>=self.maxitem: raise ValueError
if item not in self:
self.removed.discard(item)
self.added.add(item)
def discard(self, item):
if item<0 or item>=self.maxitem: raise ValueError
if item in self:
self.removed.add(item)
self.added.discard(item)
def union(self, o):
pred = lambda v: self.predicate(v) or o.predicate(v),
x = type(self)(pred, max(self.maxitem, o.maxitem))
toadd = [v for v in (self.added|o.added) if not pred(v)]
torem = [v for v in (self.removed|o.removed) if pred(v)]
x.added = set(toadd)
x.removed = set(torem)
def intersection(self, o):
pred = lambda v: self.predicate(v) and o.predicate(v),
x = type(self)(pred, min(self.maxitem, o.maxitem))
toadd = [v for v in (self.added&o.added) if not pred(v)]
torem = [v for v in (self.removed&o.removed) if pred(v)]
x.added = set(toadd)
x.removed = set(torem)
Я не совсем уверен в логике определения, добавляемой и удаляемой при объединении и пересечении, но я надеюсь, что это хорошая база для работы с вами.