2013-04-11 102 views
0

我希望能够使用来自其他列表的对象从字典中引用列表。第一个列表是矩形对象列表,第二个列表是从第一个列表中分割出来的较小的矩形对象列表。将列表与列表列表合并到一本字典中

这是我的尝试:

def merge(self, parent_list, child_list): 
    tile_dict = dict(zip(parent_list, child_list)) 
    return tile_dict 

但是我得到的错误 “Unhashable类型:pygame.Rect”。为此目的不可能使用字典吗?如果是这样,那么对于完成类似于最初预期内容的事情,适当的列表理解是什么?

+0

你能告诉我们更多关于'rect'对象吗?他们是否可变?如果不是这样,你可以通过提供某种形式的'__hash__'方法使它们变得可靠。 – mgilson 2013-04-11 16:40:28

+0

它们是具有位置,宽度和高度的pygame矩形对象。 – 2013-04-11 16:47:27

回答

4

你可以定义从pygame.Rect派生自己的类:

class HashableRect(pygame.Rect): 
    def __hash__(self): 
     return hash(tuple(self)) 

正常工作:

>>> r = HashableRect(1,2,3,4) 
>>> {r: 'something'} 
{<rect(1, 2, 3, 4)>: 'something'} 

的问题与此:pygame.Rect是一个可变的类型。你可以改变它所包含的值,因此哈希值会改变,这不应该发生。

如果您只关心对象标识,则可以返回id(self)作为散列值。

或者你也可以只将其转换为一个元组(这基本上是没有太大的那么一个四元组反正),并使用该做的查找时作为字典键:

def merge(self, parent_list, child_list): 
    tile_dict = dict(zip(map(tuple, parent_list), child_list)) 
    return tile_dict 

merged = merge(prarent_list, child_list) 
... 
child = merged[tuple(parent)] 
+0

你的答案的第二部分很好地解决了它。 – 2013-04-11 18:28:36

0

键的字典必须是可散列的,这意味着它们必须有一个__hash__方法,如果对象具有相同的“值”并且在对象的生命周期中永不改变,则该方法会产生相同的输出。 如果适用,您必须提供该散列方法,或者通过保留两个列表的列表并查找父代的每个索引的子代来模拟字典。这工作,但会O(n)查找成本。