Список манипуляций с словарем в 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 - API Facebook - нужен рабочий пример
  • Как определить функцию, которая будет проверять, имеет ли строка пробелы после завершения предложения?
  • Есть ли способ ссылаться на текущую функцию в python?
  • В чем разница между Python и Jython против IronPython vs wxPython?
  • Чтение большого файла в python
  • Запуск отладчика при ошибках в потоках
  • Как исправить TypeError: объект 'int' не является итерируемым?
  • Эквивалент Python для atoi / atof
  •  
    Interesting Posts for Van-Lav

    Как можно генерировать индексы numpy.ufunc.reduceat из объекта среза Python

    Django 1.3 Отчет об ошибке удаляет конфиденциальную информацию

    Загрузить файл в общедоступную папку на Google Диске – с помощью Python и без проверки подлинности?

    Как получить идентификаторы кластера, не являющиеся одиночными, в скудной иерархической кластеризации

    Django: проверьте, задана ли настройка переменной

    print () vs sys.stdout.write (): что и почему?

    TypeError после переопределения метода __add__

    Одинаково для rindex для списков в Python

    Как отфильтровать определенные значения от определенных слов из текстового файла и сохранить их в списке?

    Linux / Python: кодирование строки юникода для печати

    как интерпретировать эту ошибку "UnicodeDecodeError: кодек ascii не может декодировать байт 0xe2 в позиции 164: порядковый номер не в диапазоне (128)"

    Python matplotlib: память не выделяется при задании размера фигуры

    Формируйте большой массив 2d из нескольких меньших массивов 2d

    Абсолютный путь файлового объекта

    Уменьшить функцию с тремя параметрами

    Python - лучший язык программирования в мире.