Список манипуляций с словарем в python – TypeError: unhashable type: 'dict'

У меня есть список следующей формы:

oldlist = [{'x': {'a':1,'b':2}, 'y':2},{'x':{'a':6,'b':7}, 'y':2},{'x':{'a':1,'b':2}, 'y':3},{'x':{'a':1,'b':2}, 'y':2},{'x':{'a':10,'b':11}, 'y':4}] 

для преобразования в

 final = [{'x':{'a':1,'b':2},'y':[2,3,2],'count':3},{'x':{'a':6,'b':7},'y':[2],'count':1},{'x':{'a':10,'b':11},'y':[4],'count':1}] 

я пытался

 oldlist = [{'x': {'a':1,'b':2}, 'y':2},{'x':{'a':6,'b':7}, 'y':2},{'x':{'a':1,'b':2}, 'y':3},{'x':{'a':1,'b':2}, 'y':2},{'x':{'a':10,'b':11}, 'y':4}] list1=[] list2=[] list3=[] s = set([d['x'] for d in oldlist]) news=list(s) for item in oldlist: if item['x'] == news[0]: list1.append(item['y']) if item['x'] == news[1]: list2.append(item['y']) if item['x'] == news[2]: list3.append(item['y']) final=[] dic1 = {'x':news[0],'y':list1,'count':len(list1)} dic2 = {'x':news[1],'y':list2,'count':len(list2)} dic3 = {'x':news[2],'y':list3,'count':len(list3)} final.append(dic1) final.append(dic2) final.append(dic3) print final 

Получение

s = set ([d ['x'] для d в старом списке])
TypeError: unhashable type: 'dict'

Есть ли более простой способ сделать это? Плюс здесь я знал, что x может иметь только три значения, поэтому я создал три переменные list1, list2 и list3. Что, если x может иметь несколько других значений, и я должен найти аналогичный список словарей, таких как final! Он также должен работать для строк!

EDIT: Я пробовал это. Но все это перепуталось

 s = list(frozenset(oldlist[0]['x'].items())) print s for item in oldlist: s.append(frozenset(item['x'].items())) 

3 Solutions collect form web for “Список манипуляций с словарем в python – TypeError: unhashable type: 'dict'”

Вы можете использовать defaultdict где ключи – объекты frozenset созданные из значения x в исходных dicts, а значения – это список относительных y . Затем вы можете построить окончательный результат со списком и включить frozensets обратно в dicts:

 from collections import defaultdict oldlist = [{'x': {'a':1,'b':2}, 'y':2},{'x':{'a':6,'b':7}, 'y':2},{'x':{'a':1,'b':2}, 'y':3},{'x':{'a':1,'b':2}, 'y':2},{'x':{'a':10,'b':11}, 'y':4}] res = defaultdict(list) for d in oldlist: res[frozenset(d['x'].items())].append(d['y']) final = [{'x': dict(k), 'y': v, 'count': len(v)} for k, v in res.items()] # [{'y': [2, 3, 2], 'x': {'a': 1, 'b': 2}, 'count': 3}, {'y': [4], 'x': {'a': 10, 'b': 11}, 'count': 1}, {'y': [2], 'x': {'a': 6, 'b': 7}, 'count': 1}] 

Функция set может обрабатывать hashable объекты hashable , такие как строка, число, кортеж и т. Д.

Типы данных, такие как List, dict, являются типами нераскрывающихся типов, и, следовательно, функция set не может их обрабатывать.

Для большей ясности:

Что вы подразумеваете под управлением hashable в Python?

http://blog.lerner.co.il/is-it-hashable-fun-and-games-with-hashing-in-python/

Основная реализация того, что вам нужно:

 for elem in oldlist: found = False for item in newlist: if elem['x'] == item['x']: y = item.get('y',[]) item['y'] = t.append(elem['y']) found = True break if not found: newlist.append({'x':elem['x'], 'y':[elem['y']]}) 

Это даст вам ожидаемый результат

Функция set python не позволяет использовать словари, и вы не можете ее заставить, попробуйте другой метод. (Присмотритесь к комментарию на 5-й и 6-й строках)

Попробуйте этот код:

 oldlist = [{'x': {'a':1,'b':2}, 'y':2},{'x':{'a':6,'b':7}, 'y':2},{'x':{'a':1,'b':2}, 'y':3},{'x':{'a':1,'b':2}, 'y':2},{'x':{'a':10,'b':11}, 'y':4}] list1=[] list2=[] list3=[] s = [d['x'] for d in oldlist] # Placed the dictionaries in a list s = result = [dict(tupleized) for tupleized in set(tuple(item.items()) for item in s)] # This is the manual way on removing duplicates dictionaries in a list instead of using set news=list(s) for item in oldlist: if item['x'] == news[0]: list1.append(item['y']) if item['x'] == news[1]: list2.append(item['y']) if item['x'] == news[2]: list3.append(item['y']) final=[] dic1 = {'x':news[0],'y':list1,'count':len(list1)} dic2 = {'x':news[1],'y':list2,'count':len(list2)} dic3 = {'x':news[2],'y':list3,'count':len(list3)} final.append(dic1) final.append(dic2) final.append(dic3) print final 
  • Получить последний ответ
  • Как сделать списки разными?
  • Python strip () несколько символов?
  • PyCrypto на сервере разработки Google App Engine «ImportError: невозможно импортировать имя blockalgo»
  • читать массив структур из файла в python
  • Чтение даты в виде строки, не содержащей float из excel с использованием python xlrd
  • Внутренние классы: как я могу получить объект внешнего класса во время построения?
  • Является ли python Queue.queue доступным и надежным?
  • ImportError: нет модуля с именем <something>
  • Как продолжить выполнение кадра из последней попытки инструкции после обработки исключения?
  • Значение истины строки в python
  • Python - лучший язык программирования в мире.