Ошибка python: unhashable type
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'
Я получаю указанную выше ошибку в этой строке:
data=medications_minimum3(data,[drug.upper()],1)
(Я также попробовал drug.upper() без скобок)
Вот предварительный просмотр этой функции:
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
Кто-нибудь знает, что я делаю неправильно здесь?
Я знаю, что должно быть неправильно, так это то, как я вызываю эту функцию, потому что я вызываю эту функцию из другого места, и она отлично работает:
d=medications_minimum3(c,drug_input,50)
Большое спасибо за вашу помощь!
Ответы
Ответ 1
Я не думаю, что преобразование в кортеж - правильный ответ. Вам нужно пойти и посмотреть, где вы вызываете эту функцию, и убедитесь, что c
- это список списков строк или что бы вы ни разработали эту функцию для работы с
Например, вы можете получить эту ошибку, если вы передали [c]
функции вместо c
Ответ 2
counter[row[11]]+=1
Вы не показываете, что такое data
, но, по-видимому, когда вы зацикливаете его строки, row[11]
оказывается list
. Списки являются изменяемыми объектами, что означает, что они не могут использоваться в качестве словарных клавиш. Попытка использовать row[11]
в качестве ключа заставляет defaultdict
жаловаться на то, что он является изменяемым, т.е. Неотображаемым объектом.
Самое простое исправление - изменить row[11]
с list
на tuple
. Либо сделав
counter[tuple(row[11])] += 1
или путем фиксации его в вызывающем абоненте до data
передается medications_minimum3
. Кортеж просто неизменный список, поэтому он ведет себя точно так же, как и список, за исключением того, что вы не можете изменить его после его создания.
Ответ 3
Как сказал в комментарии Джим Гаррисон, нет очевидной причины, почему вы делаете одноэлементный список из drug.upper()
(который подразумевает, что препарат является строкой).
Но это не ваша ошибка, так как ваша функция medications_minimum3()
даже не использует второй аргумент (что-то вы должны исправить).
TypeError: unhashable type: 'list'
обычно означает, что вы пытаетесь использовать список как хэш-аргумент (например, для доступа к словарю). Я бы искал ошибку в counter[row[11]]+=1
- вы уверены, что row[11]
имеет правильный тип? Мне кажется, это список.
Ответ 4
File "C:\pythonwork\readthefile080410.py", line 120, in medications_minimum3
counter[row[11]]+=1
TypeError: unhashable type: 'list'
row[11]
не сотрясается. Это список. Это точно (и только), что означает сообщение об ошибке. Возможно, вам это не понравится, но это сообщение об ошибке.
Сделайте это
counter[tuple(row[11])]+=1
Также упростите.
d= [ row for row in c if counter[tuple(row[11])]>=sample_cutoff ]