Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert a list of dictionaries into a set of dictionaries

How can i make a set of dictionaries from one list of dictionaries?

Example:

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

How would you create a set of dictionaries from the list data?

NS: One dictionary is equal to another when they are structurally the same. That means, they got exactly the same keys and same values (recursively)

like image 662
BPL Avatar asked Jan 05 '23 11:01

BPL


2 Answers

A cheap workaround would be to serialize your dicts, for example:

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) 

In the long run it would make sense to wrap the whole thing in a class like SetOfDicts.

like image 155
georg Avatar answered Jan 13 '23 09:01

georg


Dictionaries are mutable and therefore not hashable in python.

You could either create a dict-subclass with a __hash__ method. Make sure that the hash of a dictionary does not change while it is in the set (that probably means that you cannot allow modifying the members). See http://code.activestate.com/recipes/414283-frozen-dictionaries/ for an example implementation of frozendicts.

If you can define a sort order on your (frozen) dictionaries, you could alternatively use a data structure based on a binary tree instead of a set. This boils down to the bisect solution provided in the link below.

See also https://stackoverflow.com/a/18824158/5069869 for an explanation why sets without hash do not make sense.

like image 34
Bernhard Avatar answered Jan 13 '23 09:01

Bernhard