Ошибка 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 ]