2011-12-30 154 views
1

我正在编码N阶马尔可夫链。Python字典与列表关键字

它是这样的:

class Chain: 
def __init__(self, order): 
    self.order = order 
    self.state_table = {} 
def train(self, next_state, *prev_states): 
    if len(prev_states) != self.order: raise ValueError("prev_states does not match chain order") 
    if prev_states in self.state_table: 
    if next_state in self.state_table[prev_states]: 
    self.state_table[prev_states][next_state] += 1 
    else: 
    self.state_table[prev_states][next_state] = 0 
    else: 
    self.state_table[prev_states] = {next_state: 0} 

Unfortunally,列表和元组是unhashable,我不能在http://stardict.sourceforge.net/Dictionaries.php下载使用它们作为关键字... 我都希望解释我的问题不够好,你明白我试图达到的目标。

任何好主意我怎么可以使用多个值的字典关键字?我不知道元组是可散列的。 但是哈希的熵似乎很低。是否有元组哈希碰撞可能?

+4

*列表和元组不可用* - 元组是可哈希的。 (如果他们的内容是可散列的,正如@larsmans正确指出的那样) – eumiro 2011-12-30 11:56:49

+4

One-space-indent?这是非常难看的。您应该遵循PEP-8并使用4格缩进。 – ThiefMaster 2011-12-30 11:57:44

+0

eumiro,谢谢!增加了关于散列冲突的后续问题 – 2011-12-30 11:58:03

回答

6

元组当它们的内容是可散列的。

>>> a = {} 
>>> a[(1,2)] = 'foo' 
>>> a[(1,[])] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unhashable type: 'list' 

至于碰撞,当我尝试了一堆非常相似的元组的,我看到他们被映射除了广泛:

>>> hash((1,2)) 
3713081631934410656 
>>> hash((1,3)) 
3713081631933328131 
>>> hash((2,2)) 
3713082714462658231 
>>> abs(hash((1,2)) - hash((1,3))) 
1082525 
>>> abs(hash((1,2)) - hash((2,2))) 
1082528247575 
3

您可以使用元组作为字典键,它们是可哈希只要他们的内容是可散的(就像@larsman说的)。

不要担心碰撞,Python的dict会照顾它。

>>> hash('a') 
12416037344 
>>> hash(12416037344) 
12416037344 
>>> hash('a') == hash(12416037344) 
True 
>>> {'a': 'one', 12416037344: 'two'} 
{'a': 'one', 12416037344: 'two'} 

在这个例子中,我带了一个字符串和一个整数。但它与元组一样。只是没有任何想法如何找到具有相同散列的两个元组。