2016-08-29 7 views
1

Как я могу сделать набор словарей из одного списка словарей?Преобразование списка словарей в набор словарей

Пример:

import copy 

v1 = {'k01': 'v01', 'k02': {'k03': 'v03', 'k04': {'k05': 'v05'}}} 
v2 = {'k11': 'v11', 'k12': {'k13': 'v13', 'k14': {'k15': 'v15'}}} 

data = [] 
N = 5 
for i in range(N): 
    data.append(copy.deepcopy(v1)) 
    data.append(copy.deepcopy(v2)) 

print data 

Как бы вы создать набор словарей из списка data?

NS: Один словарь равен другому, если они структурно одинаковы. Это значит, что они получили точно те же ключи и те же значения (рекурсивно)

+0

Каков ваш требуемый выход кортежа? –

+0

'data = set (data)'? – ForceBru

+1

@ForceBru 'TypeError: unhashable type: 'dict'' – BPL

ответ

3

Дешево обходной путь будет сериализовать dicts, например:

import json 

dset = set() 

d1 = {'a':1, 'b':{'c':2}} 
d2 = {'b':{'c':2}, 'a':1} # the same according to your definition 
d3 = {'x': 42} 

dset.add(json.dumps(d1, sort_keys=True)) 
dset.add(json.dumps(d2, sort_keys=True)) 
dset.add(json.dumps(d3, sort_keys=True)) 

for p in dset: 
    print json.loads(p) 

В долгосрочной перспективе это будет иметь смысл, чтобы обернуть все это в классе, как SetOfDicts.

+0

Nice one! Мне еще не удалось найти контрпример, похоже, он работает, даже когда клавиши перетасовываются на глубокие уровни словарей – BPL

+0

@BPL: конечно, это работает только до тех пор, пока ваши dicts (и все подэлементы) сериализуемы , – georg

+0

Достаточно честный, я могу жить с этим;) – BPL

0

Словари являются изменяемыми и, следовательно, не хешируются в python.

Вы можете создать подкласс-подкласс с помощью метода __hash__. Убедитесь, что хеш словаря не изменяется, пока он находится в наборе (это, вероятно, означает, что вы не можете разрешать изменение членов). См. http://code.activestate.com/recipes/414283-frozen-dictionaries/ для примера реализации frozendicts.

Если вы можете определить порядок сортировки в ваших (замороженных) словарях, вы можете альтернативно использовать структуру данных на основе двоичного дерева вместо набора. Это сводится к решению bisect, приведенному в ссылке ниже.

См. Также https://stackoverflow.com/a/18824158/5069869 для объяснения, почему комплекты без хэша не имеют смысла.

+0

Хорошо, вы указали, что что-то уже хорошо известно, нет решения вопроса, хотя – BPL

+0

В чем Ваш вопрос? Зачем вам набор? Вы хотите удалить дубликаты? Вы хотите использовать операции набора? – TheEspinosa

+2

@BPL Если вы уже знаете, что 'dict' не' hashable', тогда ваш вопрос не имеет смысла.Как вы можете сделать набор 'dicts'? Либо вы можете сделать набор 'ключей' в' dict', 'values' в dict или' both', BUT not dict yourself –

Смежные вопросы