2011-12-30 4 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, и я не могу использовать их в качестве ключевых слов в dicts ... Я надеюсь, объяснил свою проблему достаточно хорошо для вас, чтобы понять, чего я пытаюсь достичь.

Любые хорошие идеи, как я могу использовать несколько значений для словарного словаря?

Followup вопрос:

Я не знал, что кортежи hashable. Но энтропия хешей кажется низкой. Возможны ли хэш-коллизии для кортежей?

+4

* список и кортежи расстегиваются * - кортежи хешируются. (если их содержимое хешируется, как правильно отметили @larsmans) – eumiro

+4

Один-космос-отступ? Это очень уродливо читать. Вы должны следовать PEP-8 и использовать отступы с 4-мя пробелами. – ThiefMaster

+0

eumiro, спасибо! добавлен следующий вопрос относительно хеш-коллизий –

ответ

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

Вы можете использовать кортежи в качестве ключей словаря, они hashable до тех пор, их содержание хешируется (как сказал @larsman).

Не беспокойтесь о столкновениях, питон Питона позаботится об этом.

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

В этом примере я взял строку и целое число. Но он работает одинаково с кортежами. Просто не представлял, как найти два кортежа с одинаковыми хэшами.

Смежные вопросы