英文:
Pool objects, keep reference to pool, make illegal states irrepresentable
问题
我有一些对象,我想要"池化"它们,即将它们放入列表或集合中,使得:
- 每个对象最多出现在一个列表中,以及
- 每个对象知道它属于哪个列表。
在Python中,我可以这样做:
# 创建对象
pool1 = [obj1, obj5, obj6]
pool2 = [obj3]
pool3 = [obj8, obj7]
obj1.pool = pool1
obj2.pool = None
obj3.pool = pool2
obj4.pool = None
obj5.pool = pool1
obj6.pool = pool1
obj7.pool = pool3
obj8.pool = pool3
这可以工作,但有一个缺点,即数据结构可以表示不合法的状态,例如:
pool1 = [obj1]
pool2 = []
obj1.pool = pool2
或
pool1 = [obj1]
pool2 = [obj1]
obj1.pool = pool1
是否有更适合的数据结构用于此目的?
英文:
I have a number of objects and I'd like to "pool" them, i.e., put them into lists or sets such that
- every object appears in at most one list, and
- every object knows which list it's in.
In Python, I could do
# create objects
pool1 = [obj1, obj5, obj6]
pool2 = [obj3]
pool3 = [obj8, obj7]
obj1.pool = pool1
obj2.pool = None
obj3.pool = pool2
obj4.pool = None
obj5.pool = pool1
obj6.pool = pool1
obj7.pool = pool3
obj8.pool = pool3
This works, but has the disadvantage that the data structure can represent illegal states, e.g.,
pool1 = [obj1]
pool2 = []
obj1.pool = pool2
or
pool1 = [obj1]
pool2 = [obj1]
obj1.pool = pool1
Is there a more fitting data structure for this?
答案1
得分: 1
以下是翻译好的部分:
"I don't think there is a more fitting data structure for this, as you need the association to work in two directions (from object to list, from list to object)."
"我认为没有比这更适合的数据结构,因为你需要使关联在两个方向上工作(从对象到列表,从列表到对象)。"
"The best is probably to encapsulate this logic in a class and require that the caller uses only the provided methods to manipulate the data structure."
"最好的方法可能是将这个逻辑封装在一个类中,并要求调用者只使用提供的方法来操作数据结构。"
"In Python that could look like this:"
"在Python中,可以如下所示:"
"class Node:"
"class Node:"
"def init(self, name):"
"def init(self, name):"
"self.name = name"
"self.name = name"
"self.pool = None"
"self.pool = None"
"def repr(self):"
"def repr(self):"
"return self.name"
"return self.name"
"class Pools():"
"class Pools:"
"def init(self):"
"def init(self):"
"self._pools = {}"
"self._pools = {}"
"def assign(self, poolid, obj):"
"def assign(self, poolid, obj):"
"if poolid not in self._pools:"
"if poolid not in self._pools:"
"self._pools[poolid] = set()"
"self._pools[poolid] = set()"
"if obj.pool is not None:"
"if obj.pool is not None:"
"self._pools[obj.pool].discard(obj)"
"self._pools[obj.pool].discard(obj)"
"if poolid is not None:"
"if poolid is not None:"
"self._pools[poolid].add(obj)"
"self._pools[poolid].add(obj)"
"obj.pool = poolid"
"obj.pool = poolid"
"def unassign(self, obj):"
"def unassign(self, obj):"
"self.assign(None, obj)"
"self.assign(None, obj"
"def content(self, poolid):"
"def content(self, poolid):"
"return list(self._pools[poolid])"
"return list(self._pools[poolid])"
"# demo"
"# 演示"
"a = Node("a")"
"a = Node('a')"
"b = Node("b")"
"b = Node('b')"
"c = Node("c")"
"c = Node('c')"
"pools = Pools()"
"pools = Pools()"
"pools.assign(0, a)"
"pools.assign(0, a)"
"pools.assign(0, b)"
"pools.assign(0, b)"
"pools.assign(5, c)"
"pools.assign(5, c)"
"pools.assign(3, a)"
"pools.assign(3, a)"
"pools.assign(3, c)"
"pools.assign(3, c)"
"pools.unassign(b)"
"pools.unassign(b)"
"print(pools.content(0)) # []"
"print(pools.content(0)) # []"
"print(pools.content(3)) # ['a', 'c']"
"print(pools.content(3)) # ['a', 'c']"
"print(pools.content(5)) # []"
"print(pools.content(5)) # []"
"print(a.pool) # 3"
"print(a.pool) # 3"
"print(b.pool) # None"
"print(b.pool) # None"
"print(c.pool) # 3"
"print(c.pool) # 3"
"You could improve on this and make Pools
a subclass of dict
, but you get the idea."
"你可以改进这个并将Pools
作为dict
的子类,但你明白了这个思路。"
英文:
I don't think there is a more fitting data structure for this, as you need the association to work in two directions (from object to list, from list to object).
The best is probably to encapsulate this logic in a class and require that the caller uses only the provided methods to manipulate the data structure.
In Python that could look like this:
class Node:
def __init__(self, name):
self.name = name
self.pool = None
def __repr__(self):
return self.name
class Pools():
def __init__(self):
self._pools = {}
def assign(self, poolid, obj):
if poolid not in self._pools:
self._pools[poolid] = set()
if obj.pool is not None:
self._pools[obj.pool].discard(obj)
if poolid is not None:
self._pools[poolid].add(obj)
obj.pool = poolid
def unassign(self, obj):
self.assign(None, obj)
def content(self, poolid):
return list(self._pools[poolid])
# demo
a = Node("a")
b = Node("b")
c = Node("c")
pools = Pools()
pools.assign(0, a)
pools.assign(0, b)
pools.assign(5, c)
pools.assign(3, a)
pools.assign(3, c)
pools.unassign(b)
print(pools.content(0)) # []
print(pools.content(3)) # ['a', 'c']
print(pools.content(5)) # []
print(a.pool) # 3
print(b.pool) # None
print(c.pool) # 3
You could improve on this and make Pools
a subclass of dict
, but you get the idea.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论