亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Python哈希值字典

Python哈希值字典

繁花不似錦 2019-11-11 10:35:02
作為一種練習,并且主要是出于我的娛樂,我正在實現回溯packrat解析器。這樣做的靈感是,我想更好地了解Hygenic宏如何在類似algol的語言中工作(與通常在其中找到的無語法lisp方言相對應)。因此,通過輸入的不同傳遞可能會看到不同的語法,因此緩存的解析結果是無效的,除非我還將語法的當前版本與緩存的解析結果一起存儲。(編輯:使用鍵值集合的結果是它們應該是不可變的,但我無意公開接口以允許對其進行更改,因此可變或不可變的集合都可以)問題是python字典無法作為其他字典的鍵出現。即使使用元組(無論如何也要這樣做)也無濟于事。>>> cache = {}>>> rule = {"foo":"bar"}>>> cache[(rule, "baz")] = "quux"Traceback (most recent call last):  File "<stdin>", line 1, in <module>TypeError: unhashable type: 'dict'>>> 我想它必須一直是元組?,F在,python標準庫提供了大約所需的內容,collections.namedtuple語法非常不同,但是可以用作鍵。從以上會議繼續:>>> from collections import namedtuple>>> Rule = namedtuple("Rule",rule.keys())>>> cache[(Rule(**rule), "baz")] = "quux">>> cache{(Rule(foo='bar'), 'baz'): 'quux'}好。但是我必須為我想使用的規則中的每個可能的鍵組合創建一個類,這并不壞,因為每個解析規則都確切知道它使用的參數,因此可以同時定義該類。作為解析規則的函數。編輯:namedtuples 的另一個問題是它們嚴格處于位置??雌饋響摬煌膬蓚€元組實際上可以相同:>>> you = namedtuple("foo",["bar","baz"])>>> me = namedtuple("foo",["bar","quux"])>>> you(bar=1,baz=2) == me(bar=1,quux=2)True>>> bob = namedtuple("foo",["baz","bar"])>>> you(bar=1,baz=2) == bob(bar=1,baz=2)Falsetl'dr:如何獲得dict可以用作其他dicts的鍵的s?在回答了一些問題之后,這是我正在使用的更完整的解決方案。請注意,這做了一些額外的工作,以使所得到的指示對于實際目的幾乎不可變。當然,通過致電解決它仍然很容易,dict.__setitem__(instance, key, value)但是我們都是成年人。class hashdict(dict):    """    hashable dict implementation, suitable for use as a key into    other dicts.        >>> h1 = hashdict({"apples": 1, "bananas":2})        >>> h2 = hashdict({"bananas": 3, "mangoes": 5})        >>> h1+h2        hashdict(apples=1, bananas=3, mangoes=5)        >>> d1 = {}        >>> d1[h1] = "salad"        >>> d1[h1]        'salad'        >>> d1[h2]        Traceback (most recent call last):        ...        KeyError: hashdict(bananas=3, mangoes=5)    based on answers from       http://stackoverflow.com/questions/1151658/python-hashable-dicts    """    def __key(self):        return tuple(sorted(self.items()))    def __repr__(self):        return "{0}({1})".format(self.__class__.__name__,            ", ".join("{0}={1}".format(
查看完整描述

3 回答

?
料青山看我應如是

TA貢獻1772條經驗 獲得超8個贊

這是制作可哈希字典的簡單方法。請記住,出于明顯的原因,不要在將它們嵌入另一本詞典后對它們進行變異。


class hashabledict(dict):

    def __hash__(self):

        return hash(tuple(sorted(self.items())))


查看完整回答
反對 回復 2019-11-11
?
尚方寶劍之說

TA貢獻1788條經驗 獲得超4個贊

散列應該是不可變的-不強制執行此操作,但可信任您不要在將dict作為鍵首次使用后對其進行突變,可以使用以下方法:


class hashabledict(dict):

  def __key(self):

    return tuple((k,self[k]) for k in sorted(self))

  def __hash__(self):

    return hash(self.__key())

  def __eq__(self, other):

    return self.__key() == other.__key()

如果您確實需要更改您的命令并且仍然想將它們用作鍵,那么復雜性會爆炸數百倍-并不是說無法完成,但是我將等到非常明確的指示后再進入那令人難以置信的爛攤子! -)


查看完整回答
反對 回復 2019-11-11
?
蠱毒傳說

TA貢獻1895條經驗 獲得超3個贊

使字典可用于您的目的所需要做的就是添加__hash__方法:


class Hashabledict(dict):

    def __hash__(self):

        return hash(frozenset(self))

請注意,frozenset轉換將適用于所有詞典(即,不需要鍵是可排序的)。同樣,對字典值也沒有限制。


如果有許多字典具有相同的鍵但具有不同的值,則必須讓散列將這些值考慮在內。最快的方法是:


class Hashabledict(dict):

    def __hash__(self):

        return hash((frozenset(self), frozenset(self.itervalues())))

這比frozenset(self.iteritems())兩個原因要快。首先,該frozenset(self)步驟重用了存儲在字典中的哈希值,將不必要的調用保存到中hash(key)。其次,使用itervalues將直接訪問這些值,并避免每次進行查找時都使用by 項在內存中形成新的許多鍵/值元組的許多內存分配器調用。


查看完整回答
反對 回復 2019-11-11
  • 3 回答
  • 0 關注
  • 582 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號