2011-12-30 221 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'} 

在這個例子中,我帶了一個字符串和一個整數。但它與元組一樣。只是沒有任何想法如何找到具有相同散列的兩個元組。