Python: TypeError: unhashable type: 'list'

Я пытаюсь взять файл, который выглядит так

AAA x 111 AAB x 111 AAA x 112 AAC x 123 ... 

И используйте словарь, чтобы результат выглядел следующим образом:

 {AAA: ['111', '112'], AAB: ['111'], AAC: [123], ...} 

Это то, что я пробовал

 file = open("filename.txt", "r") readline = file.readline().rstrip() while readline!= "": list = [] list = readline.split(" ") j = list.index("x") k = list[0:j] v = list[j + 1:] d = {} if k not in d == False: d[k] = [] d[k].append(v) readline = file.readline().rstrip() 

Я продолжаю получать TypeError: unhashable type: 'list'. Я знаю, что ключевые слова в словаре не могут быть списками, но я пытаюсь превратить свою ценность в список, а не в ключ. Мне интересно, я где-то ошиблась.

Спасибо всем, кто помог мне с моим последним вопросом.

  • json.dump throwing "TypeError: {...} не является сериализуемым JSON" на, казалось бы, действительном объекте?
  • Что такое «Отображение символов типаError должно возвращать целое число ...» в этом коде python?
  • TypeError при попытке загрузить Pictures из Google App Engine в Picasa с помощью API GData
  • Сохранение массива numpy в csv вызывает несоответствие типаError
  • Python TypeError при делении исходной входной переменной на число
  • TypeError: не все аргументы, преобразованные во время форматирования строки python
  • Почему при преобразовании списка в набор и обратно я получаю нечеткий тип «list»
  • TypeError: объект 'int' не поддерживает назначение элемента
  • 5 Solutions collect form web for “Python: TypeError: unhashable type: 'list'”

    Как указано в других ответах, ошибка связана с k = list[0:j] , где ваш ключ преобразуется в список. Одна вещь, которую вы можете попробовать, – это переработать свой код, чтобы воспользоваться функцией split :

     # 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']} 

    Обратите внимание: если вы используете Python 3.x, вам нужно будет выполнить небольшую настройку, чтобы заставить ее работать правильно. Если вы откроете файл с помощью rb , вам нужно будет использовать line = line.split(b'x') (которая гарантирует, что вы разделите байт на соответствующий тип строки). Вы также можете открыть файл, используя with open('filename.txt', 'rU') as f: (или даже with open('filename.txt', 'r') as f: и он должен работать нормально.

    Вы пытаетесь использовать k (который является списком) в качестве ключа для d . Списки являются изменяемыми и не могут использоваться в качестве ключей dict.

    Кроме того, вы никогда не инициализируете списки в словаре, из-за этой строки:

     if k not in d == False: 

    Что должно быть:

     if k not in d == True: 

    Что должно быть на самом деле:

     if k not in d: 

    Причина, по которой вы получаете unhashable type: 'list' исключение unhashable type: 'list' – это потому, что k = list[0:j] устанавливает k как «срез» списка, который является другим, обычно короче, списком. Вам нужно получить только первый элемент в списке, написанный так: k = list[0] . То же самое для v = list[j + 1:] который должен быть просто v = list[2] для третьего элемента списка, возвращаемого из вызова readline.split(" ") .

    Я заметил несколько других возможных проблем с кодом, о которых я расскажу несколько. Большим является то, что вы не хотите инициализировать d каждый раз в цикле с помощью d = {} мере чтения каждой строки. Другое дело, что не стоит переименовывать переменные так же, как и встроенные, потому что это не позволит вам получить доступ к встроенному, когда вам это нужно, – и это путает других, которые используют эти имена для стандартные вещи. Поэтому по этой причине вы должны переименовать свой list переменных в нечто иное, чтобы избежать такой проблемы.

    Вот рабочая версия вашего с этими изменениями в нем, я также упростил выражение выражения if которое вы проверили, чтобы проверить, есть ли ключ в словаре – есть даже более простые неявные способы сделать это, но этот способ достаточно хорош на данный момент.

     d = {} file = open("filename.txt", "r") readline = file.readline().rstrip() while readline: lst = readline.split(" ") # split into list like ['AAA', 'x', '111'] k = lst[0] # first item v = lst[2] # third item if k not in d: # new key? d[k] = [] # initialize value d[k].append(v) readline = file.readline().rstrip() print 'd:', d 

    Вывод:

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

    TypeError происходит потому, что k – это список, поскольку он создается с использованием фрагмента из другого списка с линией k = list[0:j] . Вероятно, это должно быть что-то вроде k = ' '.join(list[0:j]) , поэтому вместо этого у вас есть строка.

    В дополнение к этому, ваш оператор if неверен, как указано в ответе Джесси, который должен читать, if k not in d или if not k in d (я предпочитаю последний).

    Вы также очищаете свой словарь на каждой итерации, так как у вас есть d = {} внутри цикла for .

    Обратите внимание, что вы также не должны использовать list или file качестве имен переменных, так как вы будете маскировать встроенные.

    Вот как я переписал бы ваш код:

     d = {} with open("filename.txt", "r") as input_file: for line in input_file: fields = line.split() j = fields.index("x") k = " ".join(fields[:j]) d.setdefault(k, []).append(" ".join(fields[j+1:])) 

    Метод dict.setdefault() выше заменяет код if k not in d коде.

      python 3.2 with open("d://test.txt") as f: k=(((i.split("\n"))[0].rstrip()).split() for i in f.readlines()) d={} for i,_,v in k: d.setdefault(i,[]).append(v) 
    Interesting Posts
    Python - лучший язык программирования в мире.