Reputation: 60691
Traceback (most recent call last):
File "<pyshell#80>", line 1, in <module>
do_work()
File "C:\pythonwork\readthefile080410.py", line 14, in do_work
populate_frequency5(e,data)
File "C:\pythonwork\readthefile080410.py", line 157, in populate_frequency5
data=medications_minimum3(data,[drug.upper()],1)
File "C:\pythonwork\readthefile080410.py", line 120, in medications_minimum3
counter[row[11]]+=1
TypeError: unhashable type: 'list'
I am getting the above error on this line:
data=medications_minimum3(data,[drug.upper()],1)
(I have also tried drug.upper() without brackets)
Here is a preview of this function:
def medications_minimum3(c,drug_input,sample_cutoff): #return sample cut off for # medications/physician
d=[]
counter=collections.defaultdict(int)
for row in c:
counter[row[11]]+=1
for row in c:
if counter[row[11]]>=sample_cutoff:
d.append(row)
write_file(d,'/pythonwork/medications_minimum3.csv')
return d
Does anyone know what I am doing wrong here?
I know that what must be wrong is the way I am calling this function, because I call this function from a different location and it works fine:
d=medications_minimum3(c,drug_input,50)
Thank you very much for your help!
Upvotes: 18
Views: 117498
Reputation: 391818
File "C:\pythonwork\readthefile080410.py", line 120, in medications_minimum3
counter[row[11]]+=1
TypeError: unhashable type: 'list'
row[11]
is unhashable. It's a list. That is precisely (and only) what the error message means. You might not like it, but that is the error message.
Do this
counter[tuple(row[11])]+=1
Also, simplify.
d= [ row for row in c if counter[tuple(row[11])]>=sample_cutoff ]
Upvotes: 0
Reputation: 304137
I don't think converting to a tuple is the right answer. You need go and look at where you are calling the function and make sure that c
is a list of list of strings, or whatever you designed this function to work with
For example you might get this error if you passed [c]
to the function instead of c
Upvotes: 10
Reputation: 7519
As Jim Garrison said in the comment, no obvious reason why you'd make a one-element list out of drug.upper()
(which implies drug is a string).
But that's not your error, as your function medications_minimum3()
doesn't even use the second argument (something you should fix).
TypeError: unhashable type: 'list'
usually means that you are trying to use a list as a hash argument (like for accessing a dictionary). I'd look for the error in counter[row[11]]+=1
-- are you sure that row[11]
is of the right type? Sounds to me it might be a list.
Upvotes: 3
Reputation: 361565
counter[row[11]]+=1
You don't show what data
is, but apparently when you loop through its rows, row[11]
is turning out to be a list
. Lists are mutable objects which means they cannot be used as dictionary keys. Trying to use row[11]
as a key causes the defaultdict
to complain that it is a mutable, i.e. unhashable, object.
The easiest fix is to change row[11]
from a list
to a tuple
. Either by doing
counter[tuple(row[11])] += 1
or by fixing it in the caller before data
is passed to medications_minimum3
. A tuple simply an immutable list, so it behaves exactly like a list does except you cannot change it once it is created.
Upvotes: 16