Types That Define '_Eq_' Are Unhashable

Types that define `__eq__` are unhashable?

Yes, if you define __eq__, the default __hash__ (namely, hashing the address of the object in memory) goes away. This is important because hashing needs to be consistent with equality: equal objects need to hash the same.

The solution is simple: just define __hash__ along with defining __eq__.

Add __hash__ and __eq__ to imported type (tkinter DoubleVar) to put it in a dictionary

You can assign methods (including __hash__ and similar) to existing classes:

# a class without explicit __hash__
class A:
def __init__(self,i):
self.i = i

a1 = A(1)
print(hash(a1)) # default hash

# define a "free" function ...
def A_hash(self):
return hash(self.i)

# ... and "binds" it to class A
A.__hash__ = A_hash

a2 = A(1)
print(hash(a2)) # new it has user defined hash

EDIT: updated code with initially unhashable object and dictionary test:

# a class without explicit __hash__
class A(list):
def __init__(self,i):
self.i = i

a1 = A(1)
# print(hash(a1)) # would be TypeError: unhashable type: 'A'

# define a "free" function ...
def A_hash(self):
return hash(self.i)

# ... and "binds" it to class A
A.__hash__ = A_hash

a2 = A(1)
print(hash(a2)) # new it has user defined hash

d = {a2:1}
print(d)

What makes a user-defined class unhashable?

Simply setting the __hash__ method to that of the tuple class is not enough. You haven't actually told it how to hash any differently. tuples are hashable because they are immutable. If you really wanted to make you specific example work, it might be like this:

class X2(list):
def __hash__(self):
return hash(tuple(self))

In this case you are actually defining how to hash your custom list subclass. You just have to define exactly how it can generate a hash. You can hash on whatever you want, as opposed to using the tuple's hashing method:

def __hash__(self):
return hash("foobar"*len(self))

How to overcome TypeError: unhashable type: 'list'

As indicated by the other answers, the error is to due to k = list[0:j], where your key is converted to a list. One thing you could try is reworking your code to take advantage of the split function:

# Using with ensures that the file is properly closed when you're done
with open('filename.txt', 'rb') as f:
d = {}
# Here we use readlines() to split the file into a list where each element is a line
for line in f.readlines():
# Now we split the file on `x`, since the part before the x will be
# the key and the part after the value
line = line.split('x')
# Take the line parts and strip out the spaces, assigning them to the variables
# Once you get a bit more comfortable, this works as well:
# key, value = [x.strip() for x in line]
key = line[0].strip()
value = line[1].strip()
# Now we check if the dictionary contains the key; if so, append the new value,
# and if not, make a new list that contains the current value
# (For future reference, this is a great place for a defaultdict :)
if key in d:
d[key].append(value)
else:
d[key] = [value]

print d
# {'AAA': ['111', '112'], 'AAC': ['123'], 'AAB': ['111']}

Note that if you are using Python 3.x, you'll have to make a minor adjustment to get it work properly. If you open the file with rb, you'll need to use line = line.split(b'x') (which makes sure you are splitting the byte with the proper type of string). You can also open the file using with open('filename.txt', 'rU') as f: (or even with open('filename.txt', 'r') as f:) and it should work fine.

TypeError: unhashable type: 'list' when using built-in set function

Sets require their items to be hashable. Out of types predefined by Python only the immutable ones, such as strings, numbers, and tuples, are hashable. Mutable types, such as lists and dicts, are not hashable because a change of their contents would change the hash and break the lookup code.

Since you're sorting the list anyway, just place the duplicate removal after the list is already sorted. This is easy to implement, doesn't increase algorithmic complexity of the operation, and doesn't require changing sublists to tuples:

def uniq(lst):
last = object()
for item in lst:
if item == last:
continue
yield item
last = item

def sort_and_deduplicate(l):
return list(uniq(sorted(l, reverse=True)))

Unhashable Type error when modifying SqlAlchemy Models

I have a "solution" for this, but I want to make sure its a viable solution and not an unstable hack.

I realize that adding the ne and eq functions to the class requires the hash function to be added in order for the model to be hashable. So this is now working:

class Role(db.Model):
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(80), unique=True)
description = db.Column(db.String(255))

def __init__(self, name, desc):
self.name = name
self.description = desc

def __repr__(self):
return '<Role: {}>'.format(str(self.name))

def __eq__(self, other):
return (self.name == other or
self.name == getattr(other, 'name', None))

def __ne__(self, other):
return not self.__eq__(other)

def __hash__(self):
return hash(self.name)

Let me know if I've done this properly, thanks!



Related Topics



Leave a reply



Submit