How to define a class that can act as dictionary key?

Discussion in 'Python' started by Lambda, Sep 15, 2009.

  1. Lambda

    Lambda Guest

    Hi,

    I'd like to define a class to use it as a dictionary key:

    class dict_entry:
    def __init__(self, term = "", doc_freq = 0):
    self.term = term
    self.doc_freq = doc_freq

    def __cmp__(self, entry):
    return isinstance(entry, dict_entry) and cmp(self.term,
    entry.term)

    def __str__(self):
    return term + ", " + str(docid)

    And later...
    entry = dict_entry(term, len(index[term]))
    self.index[entry] = []

    When I run it, it says "TypeError: unhashable instance"

    It looks like I can't use the new class object as the dictionary key.
    What should I do?
     
    Lambda, Sep 15, 2009
    #1
    1. Advertising

  2. Lambda

    Paul Rubin Guest

    Lambda <> writes:
    > When I run it, it says "TypeError: unhashable instance"
    >
    > It looks like I can't use the new class object as the dictionary key.
    > What should I do?


    You have to add a __hash__ method. Untested:

    def __hash__(self): return (self.term, self.doc_freq)

    is probably the easiest.
     
    Paul Rubin, Sep 15, 2009
    #2
    1. Advertising

  3. Lambda

    Paul Rubin Guest

    Christian Heimes <> writes:
    > > def __hash__(self): return (self.term, self.doc_freq)
    > >
    > > is probably the easiest.

    >
    > The __hash__ function must return an integer:


    Oh oops. Try:

    def __hash__(self): return hash((self.term, self.doc_freq))
     
    Paul Rubin, Sep 15, 2009
    #3
  4. Lambda a écrit :
    > Hi,
    >
    > I'd like to define a class to use it as a dictionary key:
    >


    Others already answered (define the __hash__ method). Just one point:
    the value returned by the __hash__ method should not change for the
    lifetime of the object. So if you use instance attributes to compute the
    hash, make sure these attributes won't change, else you may have a surprise:

    >>> class Foo(object):

    .... def __init__(self, a, b):
    .... self.a = a; self.b = b
    .... def __hash__(self):
    .... return hash((self.a, self.b))
    ....
    >>> f = Foo("un", "deux")
    >>> d = {f:"un deux"}
    >>> d[f]

    "un deux"
    >>> f.a = "zero"
    >>> d[f]

    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    KeyError: <__main__.Foo object at 0x9d04b2c>



    HTH
     
    Bruno Desthuilliers, Sep 15, 2009
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    1
    Views:
    422
  2. Edward
    Replies:
    3
    Views:
    922
    Edward
    Aug 4, 2006
  3. active
    Replies:
    4
    Views:
    282
    active
    Apr 3, 2007
  4. M P
    Replies:
    1
    Views:
    482
  5. John Salerno
    Replies:
    4
    Views:
    187
    Benjamin Kaplan
    Feb 27, 2012
Loading...

Share This Page