Houdini
Houdini

Reputation: 3542

The possible value of the key-value pair is unhashable?

I know that you cannot use a list as a key in a Python dictionary because it is mutable and therefore not hashable (or something like this). But I seem to be getting this error on the value, not the key. Here is my bit of code:

sp_eq = {}
sp_list = []
def build_sp_eq(row):
    # dbrefs is a dict, i.e { reference_type : id_of_that_gene}
    dbrefs = row.get('dbReference')
    print('dbrefs - ' +str(dbrefs))
    gene_ids = []
    for k, v in dbrefs.items():
        if k == 'GeneId':
            gene_ids.append(v)
    # new ID if more than 1 entrez reference
    if len(gene_ids) > 1:
                print('More than 1 GeneId for: ' +str(row.get('name')))
                sp_eq[row.get('name')] = uuid.uuid4()
    if len(gene_ids) == 0:
        # new if 0 entrez references
        sp_eq[row.get('name')] = uuid.uuid4()
        sp_list.append(row.get('name'))
    # if only one entrez ref, use the entrez uuid
    elif len(gene_ids) == 1:
        pdb.set_trace()
        print('type of row.get('name'): ' +str(type(row.get('name'))))
        sp_eq[row.get('name')] = entrez_eq.get(v)

And here is the output from the interpreter:

dbrefs - {'HGNC': ['HGNC:4931']}
dbrefs - {'HGNC': ['HGNC:4931']}
dbrefs - {'HGNC': ['HGNC:4932']}
dbrefs - {'MGI': ['MGI:1920949'], 'GeneId': ['73699']}
type of row.get('name'): <class 'str'>
Traceback (most recent call last):
  File "./gp_baseline.py", line 303, in <module>
    make_namespace(x, parser)
  File "./gp_baseline.py", line 247, in make_namespace
    build_sp_eq(row)
  File "./gp_baseline.py", line 144, in build_sp_eq
    sp_eq[row.get('name')] = entrez_eq.get(v)
TypeError: unhashable type: 'list'

So as you can see, the key in this case, row.get('name'), is of type String and should be fine. Also, as far as I understand it, using a list as the value here should be fine as well. Any ideas as to what may be happening here?

Upvotes: 0

Views: 180

Answers (1)

abarnert
abarnert

Reputation: 365587

The problem is the other half of the line, the entrez_eq.get(v). There, you're using a list v as the key to what's presumably a dict or other mapping.

(You can tell v is a list because it's a value from dbrefs, and you print dbrefs, so it's either ['MGI:1920949'] or ['73699'].)


Whenever you run into a problem like this, where you can't figure out where an error is coming from, try breaking it into pieces. Instead of this:

sp_eq[row.get('name')] = entrez_eq.get(v)

Do this:

key = row.get('name')
value = entrez_eq.get(v)
sp_eq[key] = value

Then you can find out which of the three subparts of the expression is raising—and, if you still don't know why, you have access to the intermediate values and types, so you can log them.

Upvotes: 4

Related Questions